在Python中从numpy数组中移除NaN(或其他值)的元素对

11 投票
4 回答
13481 浏览
提问于 2025-04-15 21:56

我有一个包含两列的numpy数组。例如:

a = array([[1, 5, nan, 6],
           [10, 6, 6, nan]])
a = transpose(a)

我想高效地遍历这两列,a[:, 0] 和 a[:, 1],并删除任何满足特定条件的配对,在这个例子中就是如果它们是NaN(不是一个数字)。我想到的明显方法是:

new_a = []
for val1, val2 in a:
  if val2 == nan or val2 == nan:
    new_a.append([val1, val2])

但这样做感觉有点笨。有没有更符合Python风格的numpy做法呢?

谢谢。

4 个回答

3

我并不是想贬低ig0774的回答,他的回答非常正确、符合Python的风格,而且在普通Python中确实是处理这些事情的常规方法。不过,numpy有一个布尔索引系统,也可以完成这个任务。

new_a = a[(a==a).all(1)]

我现在不太确定哪种方法更高效(或者执行得更快)。

如果你想用不同的条件来选择行,那就需要进行相应的更改,具体怎么改要看条件是什么。如果这个条件可以独立地对每个数组元素进行评估,你只需把 a==a 替换成合适的测试条件。例如,如果你想去掉所有大于100的数字所在的行,可以这样做:

new_a = a[(a<=100).all(1)]

但是如果你想做一些复杂的事情,比如去掉所有行的和大于100的行,那可能会复杂一些。如果是这种情况,如果你愿意分享你的具体条件,我可以尝试给出更具体的答案。

3

你可以把这个数组转换成一个掩码数组,然后使用compress_rows方法

import numpy as np
a = np.array([[1, 5, np.nan, 6],
           [10, 6, 6, np.nan]])
a = np.transpose(a)
print(a)
# [[  1.  10.]
#  [  5.   6.]
#  [ NaN   6.]
#  [  6.  NaN]]
b=np.ma.compress_rows(np.ma.fix_invalid(a))
print(b)
# [[  1.  10.]
#  [  5.   6.]]
31

如果你想要只保留那些没有NAN(缺失值)的行,你需要用这个表达式:

>>> import numpy as np
>>> a[~np.isnan(a).any(1)]
array([[  1.,  10.],
       [  5.,   6.]])

如果你想要那些行中没有特定数字,比如5:

>>> a[~(a == 5).any(1)]
array([[  1.,  10.],
       [ NaN,   6.],
       [  6.,  NaN]])

后面的这个表达式其实是等价于:

>>> a[(a != 5).all(1)]
array([[  1.,  10.],
       [ NaN,   6.],
       [  6.,  NaN]])

解释:首先我们来创建一个示例输入

>>> import numpy as np
>>> a = np.array([[1, 5, np.nan, 6],
...               [10, 6, 6, np.nan]]).transpose()
>>> a
array([[  1.,  10.],
       [  5.,   6.],
       [ NaN,   6.],
       [  6.,  NaN]])

这个步骤是用来确定哪些元素是NAN的

>>> np.isnan(a)
array([[False, False],
       [False, False],
       [ True, False],
       [False,  True]], dtype=bool)

这个步骤用来找出哪些行有任何元素是True的

>>> np.isnan(a).any(1)
array([False, False,  True,  True], dtype=bool)

因为我们不想要这些,所以我们对最后的表达式取反:

>>> ~np.isnan(a).any(1)
array([ True,  True, False, False], dtype=bool)

最后,我们用这个布尔数组来选择我们想要的行:

>>> a[~np.isnan(a).any(1)]
array([[  1.,  10.],
       [  5.,   6.]])

撰写回答