认识python中的inf和nan

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了认识python中的inf和nan相关的知识,希望对你有一定的参考价值。

参考技术A 认识python中的inf和nan

python中的正无穷或负无穷,使用float("inf")或float("-inf")来表示。
这里有点特殊,写成:float("inf"),float("INF")或者float('Inf')都是可以的。
当涉及 > 和 < 比较时,所有数都比无穷小float("-inf")大,所有数都比无穷大float("inf")小。
相等比较时,float("+inf")与float("+inf")、float("inf")三者相等。即:

同样地,float("-inf") == float("-inf") 返回也是True。

简单的加,减,乘操作,还是会返回无穷。

特别地,0 * float('inf') 结果为:nan
float('inf') / float('inf') 结果为:nan
float('inf') - float('inf') 结果为:nan
float('-inf') - float('-inf') 结果也为:nan

nan代表Not A Number(不是一个数),它并不等于0
因为nan不是一个数,所以相关计算都无法得到数字。
所有涉及nan的操作,返回的都是nan。

结果都是:nan
比较操作时,返回的都是False

特别注意两个float('nan')并不相等!

python中可以用math.isinf()与math.isnan()来判断数据是否为inf或nan。

numpy中也有相类似的方法可用来判断数据。

动手测试题:
0 / float('inf') == 0 / float('-inf') 结果是True 还是False?

参考资料:

Python 关于正负无穷float(‘inf’)的一些用法
https://blog.csdn.net/shennongzhaizhu/article/details/51997887

Stackoverflow.com上的问答:What is inf and nan?
https://stackoverflow.com/questions/17628613/what-is-inf-and-nan

Python pandas:如何删除 nan 和 -inf 值

【中文标题】Python pandas:如何删除 nan 和 -inf 值【英文标题】:Python pandas: how to remove nan and -inf values 【发布时间】:2018-01-26 10:59:01 【问题描述】:

我有以下数据框

           time       X    Y  X_t0     X_tp0  X_t1     X_tp1  X_t2     X_tp2
0         0.002876    0   10     0       NaN   NaN       NaN   NaN       NaN
1         0.002986    0   10     0       NaN     0       NaN   NaN       NaN
2         0.037367    1   10     1  1.000000     0       NaN     0       NaN
3         0.037374    2   10     2  0.500000     1  1.000000     0       NaN
4         0.037389    3   10     3  0.333333     2  0.500000     1  1.000000
5         0.037393    4   10     4  0.250000     3  0.333333     2  0.500000

....
1030308   9.962213  256  268   256  0.000000   256  0.003906   255  0.003922
1030309  10.041799    0  268     0      -inf   256  0.000000   256  0.003906
1030310  10.118960    0  268     0       NaN     0      -inf   256  0.000000

我尝试了以下

df.dropna(inplace=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.40)

X_train = X_train.drop('time', axis=1)
X_train = X_train.drop('X_t1', axis=1)
X_train = X_train.drop('X_t2', axis=1)
X_test = X_test.drop('time', axis=1)
X_test = X_test.drop('X_t1', axis=1)
X_test = X_test.drop('X_t2', axis=1)
X_test.fillna(X_test.mean(), inplace=True)
X_train.fillna(X_train.mean(), inplace=True)
y_train.fillna(y_train.mean(), inplace=True)

但是,每当我尝试拟合回归模型fit(X_train, y_train)时,我仍然会收到此错误ValueError: Input contains NaN, infinity or a value too large for dtype('float32').

我们如何同时删除NaN-inf 值?

【问题讨论】:

您要删除带有NaN-inf 的行还是将它们设置为默认值? 我想删除(或删除)它们 -inf 替换为NaN (df.replace(-np.inf, np.nan)) 然后执行dropna() 谢谢,但当我尝试拟合回归模型时,我仍然遇到同样的错误fit(X_train, y_train) dropping infinite values from dataframes in pandas?的可能重复 【参考方案1】:

使用pd.DataFrame.isin 并检查包含pd.DataFrame.any 的行。最后,使用布尔数组对数据帧进行切片。

df[~df.isin([np.nan, np.inf, -np.inf]).any(1)]

             time    X    Y  X_t0     X_tp0   X_t1     X_tp1   X_t2     X_tp2
4        0.037389    3   10     3  0.333333    2.0  0.500000    1.0  1.000000
5        0.037393    4   10     4  0.250000    3.0  0.333333    2.0  0.500000
1030308  9.962213  256  268   256  0.000000  256.0  0.003906  255.0  0.003922

【讨论】:

谢谢,但当我尝试拟合回归模型时仍然遇到同样的错误fit(X_train, y_train) 你对 dtype float32 有什么大的值吗? 我们如何检查?我有大约 200 万行,似乎很难手动检查 df[~df.isin([np.nan, np.inf, -np.inf]).any(1)].astype(np.float64)?【参考方案2】:

您可以将inf-inf 替换为NaN,然后选择非空行。

df[df.replace([np.inf, -np.inf], np.nan).notnull().all(axis=1)]  # .astype(np.float64) ?

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

通过df.info()检查您的列返回的类型以确保它们都符合预期(例如np.float32/64)。

【讨论】:

我仍然收到相同的错误消息。当我做df.info() 这里是输出Data columns (total 9 columns): time 1030291 non-null float64 X 1030291 non-null int64 Y 1030291 non-null int64 X_t0 1030291 non-null int64 X_tp0 1030291 non-null float64 X_t1 1030291 non-null float64 X_tp1 1030291 non-null float64 X_t2 1030291 non-null float64 X_tp2 1030291 non-null float64 dtypes: float64(6), int64(3) memory usage: 78.6 MB 其中一些列是整数。我不确定它是否会有所帮助,但请尝试通过.astype(np.float64) 将所有内容转换为浮点数。如果做不到这一点,请尝试df.describe() 检查看起来不正常的最大值或最小值。 好的,我会亚历山大。当我执行df.replace(-np.inf, np.nan) 时,它会将-inf 值转换为NaN。但是,当我们执行 df.dropna(inplace=True) 时 - 它不会删除所有 NaN 值 - 它会留下一些带有 NaN 值的行,这就是为什么我仍然遇到相同的错误。是否可以强制删除具有NaN 值的所有行? 您需要指定等于1 的轴来删除行,否则它正在删除列:df.dropna(axis=1)。另外,请参阅:***.com/questions/17477979/…【参考方案3】:
df.replace([np.inf, -np.inf], np.nan)

df.dropna(inplace=True)

【讨论】:

我喜欢这个答案,但我认为你需要:df.replace([np.inf, -np.inf], np.nan, inplace=True)【参考方案4】:

与其删除包含任何空值和无限数的行,不如将其逻辑颠倒过来,而是返回所有单元格都是有限数的行。 numpy isfinite 函数会执行此操作,如果行中的 所有 单元格是有限的,“.all(1)”只会返回 TRUE。

df = df[np.isfinite(df).all(1)]

【讨论】:

【参考方案5】:

df.replace 仅替换值上的第一次出现,从而替换错误

df = list(filter(lambda x: x!= inf, df)) 将删除所有出现的inf,然后可以使用drop 函数

【讨论】:

【参考方案6】:

我更喜欢设置选项,以便将 inf 值计算为 nan;

s1 = pd.Series([0, 1, 2])
s2 = pd.Series([2, 1, 0])
s1/s2
# Outputs:
# 0.0
# 1.0
# inf
# dtype: float64

pd.set_option('mode.use_inf_as_na', True)
s1/s2
# Outputs:
# 0.0
# 1.0
# NaN
# dtype: float64

注意你也可以使用上下文;

with pd.option_context('mode.use_inf_as_na', True):
    print(s1/s2)
# Outputs:
# 0.0
# 1.0
# NaN
# dtype: float64

【讨论】:

我在这里尝试了所有提到的解决方案。但是我的数据框中仍然有 nan 和 inf 值。任何人都可以帮忙吗?此外,我在数据框中的值是指数浮点值,我如何将其转换为小的浮点值?

以上是关于认识python中的inf和nan的主要内容,如果未能解决你的问题,请参考以下文章

Python数据分析

Python数据分析

[记] C语言中的nan和inf

MATLAB中NaN是怎么产生的,又如何具体的去解决?

IEEE754 浮点数系统中的 NaN 和 +-INF

为啥 1**Inf 的值等于 1,而不是 NaN?