在 Python 数组或 numpy 数组中过滤掉 nan 或无效的更简单方法?

simpler way to filter out nan or invalid's in Python array or a numpy array?

我有 numpy 数组 heights,其中可能有 nan。我通过以下方式清理它:

heights = numpy.asarray([ h for h in heights if not numpy.isnan(h) ])

这似乎是表达这种 simple/common 事情的一种相当冗长的方式。为了以其他方式过滤我的数组,我经常也必须这样做,并且不得不退回到数组构建,这是有效的,但我敢打赌有更好的方法来做到这一点。例如。按范围过滤...

heights = numpy.asarray(heights[lowerBound <= heights & heights < upperBound])

在 python 中失败 ,其中高度仍然是一个 numpy 数组。我回到做...

编辑:此行的错误消息是:

TypeError: ufunc 'bitwise_and' 不支持输入类型,并且根据转换规则''safe''[无法将输入安全地强制转换为任何支持的类型=41=]

/编辑

heights = numpy.asarray(heights[[h for h in heights if lowerBound <= h and h < upperBound]])

恶心。我已经使用 python 2-3 个月了,但我仍然没有真正了解如何有效且简单地使用 numpy 屏蔽系统。我来自大量使用 matlab,其中 "mask" 将是相同 shape/size 的布尔数组。例如

heights = heights(~isnan(heights));

或者……

heights(isnan(heights)) = [];

这两个看起来都超级干净。另外,在python中失败的边界示例在matlab中工作,尽管必须将括号更改为圆括号...

heights = heights(lowerBound <= heights & heights < upperBound)

如何在 python/numpy、pythonic 或其他方式中同样优雅地编写这些简单的数据转换?

它的工作原理与 Matlab 完全相同,但语法略有不同

heights = heights[~np.isnan(heights)]

演示

>>> import numpy as np
>>> heights = np.array([1.0, 3.0, np.nan, -10.0])
>>> np.asarray([ h for h in heights if not np.isnan(h) ])
array([  1.,   3., -10.])
>>> heights[~np.isnan(heights)]
array([  1.,   3., -10.])
>>>

这个有效:

heights[(10<=heights) & (heights<=90)]

这失败并出现关于模糊真值的错误

heights[10<=heights & heights<=90]

您应该指出错误,而不是直接说出来 'fails'。错误消息为我们提供了一些失败原因的线索。这通常意味着它正在尝试使用布尔数组进行简单的 'if then' 评估,尽管在这种情况下它是如何发生的并不明显。

10<=heights & heights<=90  # also fails
(10<=heights) & (heights<=90) # fine
heights & heights<=90 # ok
20<=(heights & heights)<=80  # same error
20<=heights<=80  # error
20<=heights[0]<=80  # True

进行了一些挖掘,但我现在认为问题出在 Python 和 numpy 范围计算的混合上。 Python 有一个适用于单个值的双面布尔比较。 numpy 没有那个。如果没有 (),它首先执行 heights & heights,然后尝试应用单值 Python 操作,导致 ambiguous boolean 错误。

但一般来说,布尔索引或掩码在 numpy 中的效果与在 MATLAB 中的效果一样好。 http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#boolean-array-indexing