【问题标题】:how to find the unique non nan values in a numpy array?如何在 numpy 数组中找到唯一的非 nan 值?
【发布时间】:2015-05-10 12:21:49
【问题描述】:

我想知道是否有一种干净的方式来处理 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])

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

谢谢

【问题讨论】:

    标签: python numpy nan


    【解决方案1】:

    截至 Numpy 版本 1.21.0,np.unique now returns single 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])
    

    【讨论】:

      【解决方案2】:

      正如之前的答案已经说明的那样,numpy 不能直接计算 nans,因为它无法比较 nans。 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
      

      【讨论】:

        【解决方案3】:

        我建议使用熊猫。我认为是直接替换,但是 pandas 保持原来的顺序不像 numpy。

        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。希望这会有所帮助!

        【讨论】:

          【解决方案4】:

          您可以将 isnan() 与您的 setm 一起使用,然后遍历 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 级别迭代。不仅编写的代码更少,而且对于大数组来说也更快。
          【解决方案5】:

          您可以使用np.unique 查找唯一值,结合isnan 过滤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
          猜你喜欢
          • 2018-07-04
          • 1970-01-01
          • 2016-11-08
          • 2018-04-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-01
          • 2012-03-21
          相关资源
          最近更新 更多