【问题标题】:Remove nans in multidimensional array删除多维数组中的 nans
【发布时间】:2018-01-05 03:26:06
【问题描述】:

我有一个多维数组。示例(二维):

x = np.array([[     1.,      1.,  np.nan,  np.nan],
              [     2.,  np.nan,      2.,  np.nan],
              [ np.nan,      3.,  np.nan,  np.nan]])

是否有一种简单、有效的方法可以沿轴“压缩”/“挤压”/“推出”nans?我的意思是,这样输出(这里:axis=0)就会变成:

np.array([[  1.,  1.,  np.nan,  np.nan],
          [  2.,  3.,      2.,  np.nan]])

还应该适用于超过 2 个维度。

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    你可以在非nan元素的掩码上使用argsort;使用稳定的排序算法(如合并排序)来保留非nan 元素的原始顺序:

    mask = np.isnan(x)
    cut = np.min(np.count_nonzero(mask, axis=0))
    x[np.argsort(~mask, axis=0, kind='mergesort')[cut:], np.arange(x.shape[1])]
    

    输出:

    array([[  1.,   1.,  nan,  nan],
           [  2.,   3.,   2.,  nan]])
    

    ND 版本:

    import numpy as np
    
    def nan_bouncer(x, axis=0):
        if axis != 0:
            x = np.moveaxis(x, axis, 0)
        mask = np.isnan(x)
        cut = np.min(np.count_nonzero(mask, axis=0))
        idx = tuple(np.ogrid[tuple(map(slice, x.shape[1:]))])
        res = x[(np.argsort(~mask, axis=0, kind='mergesort')[cut:],) + idx] 
        return res if axis == 0 else np.moveaxis(res, 0, axis)
    
    #demo
    data = np.random.randint(0, 3, (3, 4, 4)).astype(float)
    data /= data / data
    
    print(data)
    print(nan_bouncer(data))
    print(nan_bouncer(data, 2))
    

    样本输出:

    [[[ nan   1.   2.   1.]
      [  2.  nan  nan   2.]
      [  2.   1.   1.   2.]
      [  1.   1.   2.  nan]]
    
     [[ nan  nan   2.   1.]
      [  2.   2.  nan   1.]
      [  2.   2.   2.   2.]
      [  2.   2.  nan   1.]]
    
     [[  1.   1.  nan  nan]
      [  1.   1.   2.   1.]
      [  2.  nan   2.   1.]
      [  1.   1.   1.   2.]]]
    
    
    [[[ nan  nan  nan  nan]
      [  2.  nan  nan   2.]
      [  2.  nan   1.   2.]
      [  1.   1.  nan  nan]]
    
     [[ nan   1.   2.   1.]
      [  2.   2.  nan   1.]
      [  2.   1.   2.   2.]
      [  2.   2.   2.   1.]]
    
     [[  1.   1.   2.   1.]
      [  1.   1.   2.   1.]
      [  2.   2.   2.   1.]
      [  1.   1.   1.   2.]]]
    
    
    [[[ nan   1.   2.   1.]
      [ nan  nan   2.   2.]
      [  2.   1.   1.   2.]
      [ nan   1.   1.   2.]]
    
     [[ nan  nan   2.   1.]
      [ nan   2.   2.   1.]
      [  2.   2.   2.   2.]
      [ nan   2.   2.   1.]]
    
     [[ nan  nan   1.   1.]
      [  1.   1.   2.   1.]
      [ nan   2.   2.   1.]
      [  1.   1.   1.   2.]]]
    

    【讨论】:

    • 很好!!对于超过 2 个维度,您将如何处理?
    • @HallgeirWilhelmsen 取决于您要应用的具体规则。最简单的概括是继续将它们推向一个方向。在这种情况下,代码只需要稍作修改。
    • @HallgeirWilhelmsen 我添加了 ND 版本。
    猜你喜欢
    • 1970-01-01
    • 2021-07-28
    • 2013-11-05
    • 1970-01-01
    • 2016-01-03
    • 2015-05-22
    • 2021-04-16
    • 2014-11-17
    • 1970-01-01
    相关资源
    最近更新 更多