删除多维数组中的nans

时间:2018-01-04 18:25:28

标签: python numpy

我有一个多维数组。示例(在2D中):

NEW

是否有一种简单有效的方式来压缩" /"挤压" /"推"沿着轴线走出它的那些?我的意思是,输出(这里:axis = 0)将成为:

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

也应该使用2个以上的维度。

1 个答案:

答案 0 :(得分:4)

您可以在非argsort元素的掩码上使用nan;使用稳定的排序算法(如mergesort)来保留非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.]]]