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

Posted

技术标签:

【中文标题】sklearn错误ValueError:输入包含NaN,无穷大或对于dtype(\'float64\')来说太大的值【英文标题】:sklearn error ValueError: Input contains NaN, infinity or a value too large for dtype('float64')sklearn错误ValueError:输入包含NaN,无穷大或对于dtype('float64')来说太大的值 【发布时间】:2019-05-26 21:15:54 【问题描述】:

我正在使用 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。

【问题讨论】:

我投票结束这个,因为作者自己说他的数据是无效的,尽管一切都指向它,但他没有验证——数据相当于一个错字,这是一个关闭原因。 我的数据集也有同样的问题。最终:数据错误,而不是 scikit 学习错误。下面的大多数答案都有帮助,但具有误导性。检查检查您的数据,确保在转换为float64 时它是有限的而不是nan。错误消息很贴切 - 对于发现自己的任何人来说,这几乎肯定是问题。 对于@Owen 的记录和 +1,请检查您的输入数据并确保您在任何行或网格中都没有任何缺失值。你可以使用 Imputer 类来避免这个问题。 我对 kaggle 的 kc_house_data.csv 数据集有这个问题。我正在尝试使用以下变量进行线性回归:['bedrooms','bathrooms','sqft_living','sqft_lot','floors','waterfront','view','grade','sqft_above',' sqft_basement','纬度','sqft_living15'] 【参考方案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 函数的返回值是否为数字...

【讨论】:

文档没有提及有关此错误的任何内容我需要一种方法来摆脱我的 nupy 数组中的无限值 正如我所说:它们可能不在您的输入数组中。它们可能出现在输入和魔法输出之间发生的数学运算中。关键是所有这些数学都取决于输入的某些条件。您必须仔细阅读文档以了解您的输入是否满足这些条件。 @MarcusMüller 你能告诉我这个文档的位置,他们指定输入矩阵的要求吗?我似乎找不到您所指的“文档”。谢谢你:)【参考方案2】:

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

df = df.reset_index()

我在删除df中的一些条目时多次遇到这个问题,例如

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

【讨论】:

我爱你!尽管不知道错误的原因是什么,但这是我找到正确解决方案的罕见例子! 通过执行 df.reset_index() 它将在结果 df 中添加“索引”作为列。这可能不适用于所有场景。如果 df.reset_index(drop=True) 运行,那么它会抛出同样的错误。【参考方案3】:

这是我的功能(基于this),用于清理nanInf 和缺失单元格的数据集(用于倾斜数据集):

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(1)
    return df[indices_to_keep].astype(np.float64)

【讨论】:

为什么要丢两次nan?第一次使用dropna,然后第二次使用inf。 当我使用这个函数清理我的数据集时,我丢失了一些数据。有什么理由吗??? 这是 only 有效的答案。我在 SO 上尝试了其他 20 个没有用的答案。我认为这个需要更多的支持。【参考方案4】:

这是失败的检查:

https://github.com/scikit-learn/scikit-learn/blob/0.17.X/sklearn/utils/validation.py#L51

说什么

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。

【讨论】:

【参考方案5】:

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

摆脱无限的价值。

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

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

df.fillna(999, inplace=True)

【讨论】:

【参考方案6】:

我的输入数组的维度有偏差,因为我的输入 csv 有空格。

【讨论】:

对于pandas,我只是用dropnapandas.pydata.org/pandas-docs/stable/generated/…【参考方案7】:

有了这个版本的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
...

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

【讨论】:

【参考方案8】:

这里没有一个答案对我有用。这是行得通的。

Test_y = np.nan_to_num(Test_y)

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

【讨论】:

使用您对我的 x_train 和 x_test 的建议为我解决了问题。【参考方案9】:

尝试选择行子集后出现错误:

df = df.reindex(index=my_index)

原来my_index 包含df.index 中不包含的值,因此重新索引函数插入了一些新行并用nan 填充它们。

【讨论】:

【参考方案10】:

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

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

编辑:最初建议的 X.as_matrix() 是Deprecated

【讨论】:

【参考方案11】:

删除所有无限值:

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

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]])

【讨论】:

【参考方案12】:

我遇到了同样的错误。在进行任何替换、替换等操作之前,它与 df.fillna(-99999, inplace=True) 一起工作

【讨论】:

这是一个肮脏的修复。您的数组包含nan 值是有原因的;你应该找到它。 数据可能包含 nan,这提供了一种将其替换为他/她认为可接受的值的数据的方法【参考方案13】:

我想提出一个适合我的 numpy 解决方案。线

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

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

【讨论】:

【参考方案14】:

在我的情况下,问题是许多 scikit 函数返回 numpy 数组,这些数组没有 pandas 索引。因此,当我使用这些 numpy 数组构建新的 DataFrame,然后尝试将它们与原始数据混合时,出现了索引不匹配。

【讨论】:

【参考方案15】:
dataset = dataset.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)

这对我有用

【讨论】:

【参考方案16】:

如果您正在运行估算器,则可能是您的学习率太高。我也无意中通过了错误的数组进行了网格搜索,最终以 500 的学习率进行了训练,我可以看到这会导致训练过程出现问题。

基本上,不一定只有您的输入必须全部有效,中间数据也必须有效。

【讨论】:

【参考方案17】:

DecisionTreeClassifier 输入检查似乎出现问题,试试

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

【讨论】:

【参考方案18】:

我遇到了同样的问题,在我的情况下,答案只是我的 CSV 中有一个没有值的单元格(“x,y,z,”)。为我设置一个默认值。

【讨论】:

【参考方案19】:

试试

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))

【讨论】:

以上是关于sklearn错误ValueError:输入包含NaN,无穷大或对于dtype('float64')来说太大的值的主要内容,如果未能解决你的问题,请参考以下文章

sklearn 的 PLSRegression:“ValueError:数组不得包含 infs 或 NaN”

ValueError:在 defaultdict 上使用 sklearn 时样本数不一致

Sklearn:ValueError:发现样本数量不一致的输入变量:[1, 6]

ValueError:模型的特征数量必须与输入匹配(sklearn)

ValueError: bad input shape (560, 5) sklearn

sklearn管道ValueError:除连接轴外的所有输入数组维度必须完全匹配