numpy 如果列表包含np.NaN,如何得到两个列表的逻辑掩码

anhgbhbe  于 2023-05-17  发布在  其他
关注(0)|答案(3)|浏览(100)

当列表中有np. NaN时,逻辑OR和逻辑AND似乎不起作用。我举了一个简单的例子:如果我用np.NaN填充ndarray,它就不能正常工作:

import numpy as np
m =10
l1, l2 = np.array([np.NaN] * m), np.array([np.NaN] * m)
l1[3] = 5
l2[3] = 5
l1[5] = 6
l2[5] = 6
l2[7] = 7
l1[8] = 8

mask1 = (l1 != np.NaN) & (l2 != np.NaN)
mask0 = (l1 == np.NaN) | (l2 == np.NaN)
print("Lists:")
print(l1)
print(l2)
print()
print("Masks:")
print(mask1)
print(mask0)

它打印:

Lists:
[nan nan nan  5. nan  6. nan nan  8. nan]
[nan nan nan  5. nan  6. nan  7. nan nan]

Masks:
[ True  True  True  True  True  True  True  True  True  True] # not true
[False False False False False False False False False False] # not true

我期望:

Masks:
[False False False  True False  True False False False False]
[ True  True  True False  True False  True  True  True  True]

我做了一个测试,我改变了np.NaN为None,这解决了一个逻辑操作的问题,但是在我的代码中,我从列表中计算项目,我必须将项目与值进行比较。然后我得到TypeError:
TypeError:“NoteType”和“int”的示例之间不支持“<”
如何将所有np.NaN更改为None?

lymnna71

lymnna711#

不能使用==和!= on np.nan值nan不等于nan
here一些深刻的解释
在算法中引入np.isnan()

mask1 = (~np.isnan(l1)) & (~np.isnan(l2))
mask0 = (np.isnan(l1)) | (np.isnan(l2))
bakd9h0s

bakd9h0s2#

我觉得很简单。

mask1 = l1==l2 
mask2 = ~mask1
v09wglhw

v09wglhw3#

让我们更详细地探讨替代方案
您的阵列(类似l2

In [18]: l1
Out[18]: array([nan, nan, nan,  5., nan,  6., nan, nan,  8., nan])

In [19]: l1.dtype
Out[19]: dtype('float64')

使用isnan测试:

In [20]: np.isnan(l1)
Out[20]: 
array([ True,  True,  True, False,  True, False,  True,  True, False,
        True])

并将它们组合:

In [21]: np.isnan(l1)|np.isnan(l2)
Out[21]: 
array([ True,  True,  True, False,  True, False,  True,  True,  True,
        True])

由于nan传播,我们可以在

In [25]: l1+l2
Out[25]: array([nan, nan, nan, 10., nan, 12., nan, nan, nan, nan])

l1==l2相当于测试l1-l2是否为0。

In [27]: l1-l2
Out[27]: array([nan, nan, nan,  0., nan,  0., nan, nan, nan, nan])

In [28]: l1==l2
Out[28]: 
array([False, False, False,  True, False,  True, False, False, False,
       False])

我可以运行一些timeit测试,但对于如此小的数组,它们不会告诉我们很多。np.isnan是一个numpy编译的函数,速度足够快。
nan的独特之处在于它永远不等于自身。加强你的真或假数组。

In [36]: l1==np.nan
Out[36]: 
array([False, False, False, False, False, False, False, False, False,
       False])

使用None创建数组,创建一个对象dtype(非浮点型)

In [38]: l11
Out[38]: array([None, None, None, 5, None, 6, None, None, 8, None], dtype=object)

None与只有一个None不同,因此is/==为真,但大小比较没有意义

In [51]: None is None
Out[51]: True

In [52]: None==None
Out[52]: True

In [53]: None==3
Out[53]: False

In [54]: None<3
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[54], line 1
----> 1 None<3

TypeError: '<' not supported between instances of 'NoneType' and 'int'

np.isnan不能在这个l11对象dtype数组上运行,因为它需要浮点数
我相信pandas有一些比np.isnan更广泛的测试,但我没有在这台计算机上安装。

相关问题