从numpy数组中删除在Python中为NaN(或另一个值)的元素对

2024-05-29 03:42:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数组,在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核做的方式?

谢谢。


Tags: orinnumpynewforif数组nan
3条回答

这并不是贬低ig0774的答案,它是完全有效的和Python的,事实上是用普通Python做这些事情的正常方式,但是:numpy支持布尔索引系统,它也可以做这项工作。

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

我不确定哪种方式更有效(或执行更快)。

如果要使用不同的条件来选择行,则必须对其进行更改,具体取决于条件。如果可以独立地对每个数组元素求值,则可以用适当的测试替换a==a,例如消除所有可以执行的大于100的行

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

但是如果你想做一些花哨的事情,涉及到一行中的所有元素(比如删除所有总和超过100的行),那可能会更复杂。如果是这样的话,我可以试着在一个更具体的答案编辑,如果你想分享你的确切条件。

可以将数组转换为masked array,并使用^{} method

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.]]

如果只接受没有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.]])

相关问题 更多 >

    热门问题