sklearn 错误 ValueError:输入包含 NaN、无穷大或对于 dtype('float64') 来说太大的值

2025-03-04 08:28:00
admin
原创
275
摘要:问题描述:我正在使用 sklearn,但在亲和力传播方面遇到了问题。我构建了一个输入矩阵,但一直出现以下错误。ValueError: Input contains NaN, infinity or a value too large for dtype('float64'). 我已经跑了np.isnan(ma...

问题描述:

我正在使用 sklearn,但在亲和力传播方面遇到了问题。我构建了一个输入矩阵,但一直出现以下错误。

ValueError: Input contains NaN, infinity or a value too large for dtype('float64').

我已经跑了

np.isnan(mat.any()) #and gets False
np.isfinite(mat.all()) #and gets True

我尝试使用

mat[np.isfinite(mat) == True] = 0

删除无限值,但这也不起作用。我该怎么做才能摆脱矩阵中的无限值,以便我可以使用亲和传播算法?

我正在使用 anaconda 和 python 2.7.9。


解决方案 1:

这可能发生在 scikit 中,这取决于你正在做什么。我建议阅读你正在使用的函数的文档。你可能正在使用一个依赖于矩阵是否为正定的函数,但该函数不满足该标准。

编辑:我怎么会错过呢:

np.isnan(mat.any()) #and gets False
np.isfinite(mat.all()) #and gets True

显然是错误的。正确的应该是:

np.any(np.isnan(mat))

np.all(np.isfinite(mat))

您想检查任何元素是否为 NaN,而不是any函数的返回值是否是数字......

解决方案 2:

在将sklearnpandas结合使用时,我收到了相同的错误消息。 我的解决方案是df在运行任何 sklearn 代码之前重置数据框的索引:

df = df.reset_index()

我多次遇到过这个问题,当我删除我的一些条目,df

df = df[df.label=='desired_one']

解决方案 3:

这是我的功能(基于此nan),用于清理、Inf和缺失单元格的数据集(针对倾斜的数据集):

import pandas as pd
import numpy as np

def clean_dataset(df):
    assert isinstance(df, pd.DataFrame), "df needs to be a pd.DataFrame"
    df.dropna(inplace=True)
    indices_to_keep = ~df.isin([np.nan, np.inf, -np.inf]).any(axis=1)
    return df[indices_to_keep].astype(np.float64)

解决方案 4:

大多数情况下,摆脱无限值和空值可以解决这个问题。

摆脱无限的值。

df.replace([np.inf, -np.inf], np.nan, inplace=True)

按照你喜欢的方式删除空值,具体值如 999、平均值,或者创建自己的函数来估算缺失值

df.fillna(999, inplace=True)

解决方案 5:

这是失败的检查:

也就是说

def _assert_all_finite(X):
    """Like assert_all_finite, but only for ndarray."""
    X = np.asanyarray(X)
    # First try an O(n) time, O(1) space solution for the common case that
    # everything is finite; fall back to O(n) space np.isfinite to prevent
    # false positives from overflow in sum method.
    if (X.dtype.char in np.typecodes['AllFloat'] and not np.isfinite(X.sum())
            and not np.isfinite(X).all()):
        raise ValueError("Input contains NaN, infinity"
                         " or a value too large for %r." % X.dtype)

因此,请确保您的输入中没有 NaN 值。并且所有这些值实际上都是浮点值。任何值都不应是 Inf。

解决方案 6:

我的输入数组的尺寸是倾斜的,因为我的输入 csv 有空白处。

解决方案 7:

这里的答案对我都不起作用。这个答案对我有用。

Test_y = np.nan_to_num(Test_y)

它用高有限值替换无穷大值,用数字替换 nan 值

解决方案 8:

问题似乎发生在 DecisionTreeClassifier 输入检查中,请尝试

X_train = X_train.replace((np.inf, -np.inf, np.nan), 0).reset_index(drop=True)

解决方案 9:

使用这个版本的python 3:

/opt/anaconda3/bin/python --version
Python 3.6.0 :: Anaconda 4.3.0 (64-bit)

查看错误的详细信息,我找到了导致失败的代码行:

/opt/anaconda3/lib/python3.6/site-packages/sklearn/utils/validation.py in _assert_all_finite(X)
     56             and not np.isfinite(X).all()):
     57         raise ValueError("Input contains NaN, infinity"
---> 58                          " or a value too large for %r." % X.dtype)
     59 
     60 

ValueError: Input contains NaN, infinity or a value too large for dtype('float64').

由此,我能够提取正确的方法来测试我的数据发生了什么,使用与错误消息给出的失败相同的测试:np.isfinite(X)

然后通过一个快速而肮脏的循环,我发现我的数据确实包含nans

print(p[:,0].shape)
index = 0
for i in p[:,0]:
    if not np.isfinite(i):
        print(index, i)
    index +=1

(367340,)
4454 nan
6940 nan
10868 nan
12753 nan
14855 nan
15678 nan
24954 nan
30251 nan
31108 nan
51455 nan
59055 nan
...

现在我要做的就是删除这些索引的值。

解决方案 10:

我遇到了同样的错误,在我的例子中,X 和 y 是数据框,所以我必须先将它们转换为矩阵:

X = X.values.astype(np.float)
y = y.values.astype(np.float)

编辑:最初建议的 X.as_matrix() 已被弃用

解决方案 11:

我尝试选择一部分行后出现错误:

df = df.reindex(index=my_index)

事实证明my_index包含不包含在中的值df.index,因此 reindex 函数插入了一些新行并用 填充它们nan

解决方案 12:

删除所有无限值:

(并用该列的最小值或最大值替换)

import numpy as np

# generate example matrix
matrix = np.random.rand(5,5)
matrix[0,:] = np.inf
matrix[2,:] = -np.inf
>>> matrix
array([[       inf,        inf,        inf,        inf,        inf],
       [0.87362809, 0.28321499, 0.7427659 , 0.37570528, 0.35783064],
       [      -inf,       -inf,       -inf,       -inf,       -inf],
       [0.72877665, 0.06580068, 0.95222639, 0.00833664, 0.68779902],
       [0.90272002, 0.37357483, 0.92952479, 0.072105  , 0.20837798]])

# find min and max values for each column, ignoring nan, -inf, and inf
mins = [np.nanmin(matrix[:, i][matrix[:, i] != -np.inf]) for i in range(matrix.shape[1])]
maxs = [np.nanmax(matrix[:, i][matrix[:, i] != np.inf]) for i in range(matrix.shape[1])]

# go through matrix one column at a time and replace  + and -infinity 
# with the max or min for that column
for i in range(matrix.shape[1]):
    matrix[:, i][matrix[:, i] == -np.inf] = mins[i]
    matrix[:, i][matrix[:, i] == np.inf] = maxs[i]

>>> matrix
array([[0.90272002, 0.37357483, 0.95222639, 0.37570528, 0.68779902],
       [0.87362809, 0.28321499, 0.7427659 , 0.37570528, 0.35783064],
       [0.72877665, 0.06580068, 0.7427659 , 0.00833664, 0.20837798],
       [0.72877665, 0.06580068, 0.95222639, 0.00833664, 0.68779902],
       [0.90272002, 0.37357483, 0.92952479, 0.072105  , 0.20837798]])

解决方案 13:

我发现在新列上调用 pct_change 后,其中一行存在 nan。我使用以下代码删除了 nan 行

df = df.replace([np.inf, -np.inf], np.nan)
df = df.dropna()
df = df.reset_index()

解决方案 14:

我遇到了同样的错误。它df.fillna(-99999, inplace=True)在进行任何替换、替代等之前都可以正常工作

解决方案 15:

我想提出一个对我而言效果很好的 numpy 解决方案。

from numpy import inf
inputArray[inputArray == inf] = np.finfo(np.float64).max

用最大的 float64 数字替换 numpy 数组的所有无限值。

解决方案 16:

噗!!就我而言,问题出在 NaN 值上……

您可以使用此函数列出包含 NaN 的列

your_data.isnull().sum()

然后您可以在数据集文件中填充这些 NAN 值。

以下是如何“用零替换 NaN,用大的有限数替换无穷大”的代码。

your_data[:] = np.nan_to_num(your_data)

来自numpy.nan_to_num

解决方案 17:

经过长时间的处理,我意识到这是因为在训练集和测试集的拆分中,有些数据列对于所有数据行都是相同的。然后某些算法中的某些计算可能会导致无穷大的结果。如果您使用的数据是相近的行更可能相似,那么对数据进行混洗可能会有所帮助。这是 scikit 的一个错误。我使用的是 0.23.2 版本。

解决方案 18:

如果您碰巧使用“kc_house_data.csv”数据集(一些评论者和许多数据科学新手似乎都在使用该数据集,因为它出现在许多流行的课程材料中),那么该数据是有错误的,也是错误的真正来源。

为了解决这个问题,自 2022 年起:

  • 删除 csv 文件中的最后一行(空行)

  • 有两行包含一个空数据值“x,x,,x,x” - 要修复它,不要删除逗号,而是添加一个随机整数值,如 2000,因此它看起来像这样“x,x,2000,x,x”

不要忘记在您的项目中保存并重新加载。

所有其他答案都是有帮助的和正确的,但在这种情况下不是:

如果您使用 kc_house_data.csv, 则需要修复文件中的数据,其他任何方法都无济于事,空数据字段将随机移动其他数据并产生难以追踪到源头的奇怪错误!

解决方案 19:

在我的案例中,问题在于许多 scikit 函数返回的 numpy 数组缺少 pandas 索引。因此,当我使用这些 numpy 数组构建新的 DataFrames,然后尝试将它们与原始数据混合时,索引不匹配。

解决方案 20:

dataset = dataset.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)

这对我有用

解决方案 21:

我遇到了同样的问题,就我的情况而言,答案很简单,我的 CSV 中有一个单元格没有值(“x,y,z,,”)。输入默认值就可以解决这个问题。

解决方案 22:

使用isneginf可能会有帮助。http
://docs.scipy.org/doc/numpy/reference/generated/numpy.isneginf.html#numpy.isneginf

x[numpy.isneginf(x)] = 0 #0 is the value you want to replace with

解决方案 23:

注意:仅当您有意识地想要保留NaN数据集中的条目时,此解决方案才适用。

当我使用某些scikit-learn功能时发生了此错误(在我的情况下GridSearchCV:)。在后台,我使用的是xgboost XGBClassifier,它可以优雅地处理NaN数据。但是,GridSearchCV我使用的sklearn.utils.validation模块通过调用函数强制输入数据中缺少缺失数据_assert_all_finite。这最终导致了错误:

ValueError: Input contains NaN, infinity or a value too large for dtype('float64')

旁注:_assert_all_finite接受一个allow_nan参数,如果设置为True,则不会引起问题。但是,scikit-learn API 不允许我们控制这个参数。

解决方案

我的解决方案是使用patch模块来使该_assert_all_finite函数静音,这样它就不会raise ValueError。以下是代码片段

import sklearn
with mock.patch("sklearn.utils.validation._assert_all_finite"):
    # your code that raises ValueError

这将用一个虚拟模拟函数来替代,_assert_all_finite所以它不会被执行。

请注意,修补不是推荐的做法,可能会导致不可预测的行为!


编辑:
此Pull 请求应该可以解决该问题(尽管截至 2022 年 1 月修复程序尚未发布)

解决方案 24:

如果您正在运行估算器,则可能是您的学习率太高。我意外地将错误的数组传递给网格搜索,最终以 500 的学习率进行训练,我发现这会导致训练过程出现问题。

基本上,不仅您的输入必须全部有效,而且中间数据也必须有效。

解决方案 25:

在我的例子中,算法要求数据在 (0,1) 之间。我的解决方案相当粗暴,就是在所有需要的值上添加一个小的随机数:

y_train = pd.DataFrame(y_train).applymap(lambda x: x + np.random.rand()/100000.0)["col_name"]
y_train[y_train >= 1] = 0.999999

而y_train在[0,1]范围内。

这绝对不适合所有情况,因为你弄乱了输入数据,但如果你的数据稀疏且只需要快速预测,这可能是一个解决方案

解决方案 26:

sklearn=1.1.2

蟒蛇=3.9

在我的情况下,带有 standardize=True 的 PowerScaler 导致了问题。正如 @TomaszBartkowiak 已经解释的那样,断言是在 sklearn.utils.validation._asser_all_finite 中提出的,它似乎在我的情况下在聚合(如 np.sum)之前的很多地方使用。

我手动检查了所有条件(dtypes、nan、inf、-inf),发现没有理由导致断言仍然失败。所以我只是暂时注释掉了 _asser_all_finit 第 108 行中的检查:

...
is_float = X.dtype.kind in "fc"
if True:#is_float and (np.isfinite(_safe_accumulator_op(np.sum, X))):
    pass
elif is_float:
...

成功执行 PowerScaler 后,我将代码改回来。这虽然快速而粗略,但如果您真的对您的数据有信心,并且这种情况似乎毫无原因地发生,您可以通过这种方式解决它。但一般来说,数据确实在某处包含 INF/-INF 的可能性非常高。所以最好深入挖掘。对于 Scaler,您可以轻松在输出中找到带有 INF/-INF 的列,以便您可以返回并在输入数据中再次检查这些列。我不知道为什么在使用 Scaler 之前检查不起作用......

解决方案 27:

尝试

mat.sum()

如果您的数据总和为无穷大(大于最大浮点值 3.402823e+38),则会出现该错误。

从 scikit 源代码中查看 validation.py 中的 _assert_all_finite 函数:

if is_float and np.isfinite(X.sum()):
    pass
elif is_float:
    msg_err = "Input contains {} or a value too large for {!r}."
    if (allow_nan and np.isinf(X).any() or
            not allow_nan and not np.isfinite(X).all()):
        type_err = 'infinity' if allow_nan else 'NaN, infinity'
        # print(X.sum())
        raise ValueError(msg_err.format(type_err, X.dtype))
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3970  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2740  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   79  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   87  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   74  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用