如何在NumPy数组中找到唯一的非NaN值?

24

我想知道在numpy中处理nan的清晰方法是否存在。

my_array1=np.array([5,4,2,2,4,np.nan,np.nan,6])
print my_array1
#[  5.   4.   2.   2.   4.  nan  nan   6.]
print set(my_array1)
#set([nan, nan, 2.0, 4.0, 5.0, 6.0])

我本以为它最多应该返回一个 nan 值。为什么会返回多个 nan 值呢? 我想知道在 numpy 数组中有多少个唯一的非 nan 值。

谢谢。

5个回答

34
您可以使用np.uniqueisnan结合使用,以筛选出NaN值并找到唯一的值:
In [22]:

my_array1=np.array([5,4,2,2,4,np.nan,np.nan,6])
np.unique(my_array1[~np.isnan(my_array1)])
Out[22]:
array([ 2.,  4.,  5.,  6.])

为什么会有多个NaN值呢?因为NaN值无法进行正常的比较:

In [23]:

np.nan == np.nan
Out[23]:
False

所以你需要使用 isnan 来执行正确的比较

使用 set

In [24]:

set(my_array1[~np.isnan(my_array1)])
Out[24]:
{2.0, 4.0, 5.0, 6.0}

您可以调用上述任何一个对象的len方法来获取大小:

In [26]:

len(np.unique(my_array1[~np.isnan(my_array1)]))
Out[26]:
4

从Numpy版本1.21.0开始,np.unique现在返回单个NaN - aerobiomat

9

我建议使用Pandas。我认为它可以直接替换,但是与NumPy不同,Pandas保持原始顺序。

import numpy as np
import pandas as pd

my_array1=np.array([5,4,2,2,4,np.nan,np.nan,6])

np.unique(my_array1)
# array([ 2.,  4.,  5.,  6., nan, nan])

pd.unique(my_array1)
# array([ 5.,  4.,  2., nan,  6.]) 

我正在使用numpy 1.17.4和pandas 0.25.3。希望这可以帮到您!


2

正如之前的回答所述,numpy不能直接计算nan,因为它无法比较nan。numpy.ma.count_masked是你的好朋友。例如,像这样:

>>> import numpy.ma as ma
>>> a = np.array([ 0.,  1., np.nan, np.nan,  4.])
>>> a
np.array([ 0.,  1., nan, nan,  4.])
>>> a_masked = ma.masked_invalid(a)
>>> a_masked
masked_array(data=[0.0, 1.0, --, --, 4.0],
             mask=[False, False,  True,  True, False],
       fill_value=1e+20)
>>> ma.count_masked(a_masked)
2

1
截至Numpy 1.21.0版本,np.unique现在返回单个NaN
>>> a = np.array([8, 1, np.nan, 3, np.inf, np.nan, -np.inf, -2, np.nan, 3])
>>> np.unique(a)
array([-inf,  -2.,   1.,   3.,   8.,  inf,  nan])

0

您可以在setm中使用isnan(),然后迭代isnan()数组的结果并删除所有NaN对象。

my_array1=np.array([5,4,2,2,4,np.nan,np.nan,6])
print my_array1
#[  5.   4.   2.   2.   4.  nan  nan   6.]
print set(my_array1)
#set([nan, nan, 2.0, 4.0, 5.0, 6.0])
for i,is_nan in enumerate(np.isnan(list(my_array1))):
    if is_nan:
        del my_array1[i]

如果你想从一个数组中删除所有的NaN元素,一个更好的方法是这样做: my_array1 = my_array1[~np.isnan(my_array1)] 它将以向量化的方式操作(很可能使用优化的代码),而不是在Python层面迭代。 不仅如此,它写起来的代码更少,对于大型数组来说也更快。 - ZeDuS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接