与 NaN 相等的元素比较
Posted
技术标签:
【中文标题】与 NaN 相等的元素比较【英文标题】:Element-wise comparison with NaNs as equal 【发布时间】:2019-02-05 18:52:17 【问题描述】:如果我运行以下代码:
dft1 = pd.DataFrame('a':[1, np.nan, np.nan])
dft2 = pd.DataFrame('a':[1, 1, np.nan])
dft1.a==dft2.a
结果是
0 True
1 False
2 False
Name: a, dtype: bool
我怎样才能使结果成为
0 True
1 False
2 True
Name: a, dtype: bool
即,np.nan == np.nan 的计算结果为 True。
我认为这是基本功能,我一定是在问一个重复的问题,但我花了很多时间在 SO 或 Google 中搜索,但找不到。
【问题讨论】:
【参考方案1】:想不出一个已经为你做这个的函数(奇怪)所以你可以自己做:
dft1.eq(dft2) | (dft1.isna() & dft2.isna())
a
0 True
1 False
2 True
注意括号的存在。在 pandas 中使用重载的按位运算符时需要注意优先级。
另一个选择是使用np.nan_to_num
,如果你确定两个DataFrame的索引和列是相同的,那么这个结果是有效的:
np.nan_to_num(dft1) == np.nan_to_num(dft2)
array([[ True],
[False],
[ True]])
np.nan_to_num
用一些填充值填充 NaN(数字为 0,字符串数组为 'nan')。
【讨论】:
谢谢。我更喜欢第一个选项。如果没有更好的结果,我会在几天后选择你的答案。 我猜这将等同于None
和 np.nan
我还要假设这些总是浮动的,所以不会有任何None
【参考方案2】:
将np.isclose
与equal_nan=True
一起使用:
np.isclose(dft1, dft2, equal_nan=True, rtol=0, atol=0)
array([[ True],
[False],
[ True]])
将atol
和rtol
都设置为零很重要,以避免在相似值上出现相等断言。
【讨论】:
酷!我隐约记得有一个带有equal_nan
参数的函数,但我并没有想到。
如果在这里将公差设置为 0 会怎样?
不过,您可能必须将 tols 设置为 0,对吗? .. 啊,被打败了【参考方案3】:
因为 np.nan 不等于 np.nan
np.nan==np.nan
Out[609]: False
dft1.a.fillna('NaN')==dft2.a.fillna('NaN')
Out[610]:
0 True
1 False
2 True
Name: a, dtype: bool
【讨论】:
有趣的是,您可能还可以转换为字符串并重复。 ++ 谢谢文。我见过我的同事这样做,但有时它可能很危险,因为这个系列中可能已经存在这个神奇的词('NaN'
)。
或许可以改成dft1.astype(str).eq(dft2.astype(str))
【参考方案4】:
np.nan
被定义为不等于np.nan
。
迭代
检查每一对是否相等或全部np.nan
def naneq(t):
return (t[0] == t[1]) or np.isnan(t).all()
[*map(naneq, zip(dft1.a, dft2.a))]
[True, False, True]
nunique
计算唯一值。确保设置参数dropna=False
pd.concat([dft1, dft2], axis=1).nunique(1, 0) == 1
0 True
1 False
2 True
dtype: bool
【讨论】:
以上是关于与 NaN 相等的元素比较的主要内容,如果未能解决你的问题,请参考以下文章