更简单的方法来过滤掉Python数组或numpy数组中的nan或invalid?

时间:2015-02-03 22:53:41

标签: python arrays matlab python-2.7 numpy

我有numpy数组heights,其中可能有nan个。我通过这样做来清理它:

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

这似乎是表达这种简单/常见事物的相当冗长的方式。我经常必须这样做以便以其他方式过滤我的阵列,并且必须回到阵列构建,这有效,但我敢打赌有更好的方法来做到这一点。例如。按范围过滤......

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

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

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

TypeError:ufunc&#39; bitwise_and&#39;不支持输入类型,并且根据投射规则无法安全地将输入强制转换为任何支持的类型&#39;&#39;

/ EDIT

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

毛。我现在已经使用python 2-3个月,但我仍然没有真正得到如何有效和简单地使用numpy masking系统。我来自大量使用matlab,其中一个&#34;面具&#34;将是一系列相同形状/大小的布尔。 E.g。

heights = heights(~isnan(heights));

或者......

heights(isnan(heights)) = [];

这两个看起来都很干净。此外,在python中失败的bounds示例在matlab中工作,尽管括号必须更改为括号...

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

我如何在python / numpy,pythonic或其他方面优雅地编写这些简单的数据转换?

2 个答案:

答案 0 :(得分:5)

它的工作原理与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.])
>>>

答案 1 :(得分:2)

这有效:

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

这失败了,有关模糊真值的错误

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

您应该指定错误,而不仅仅是说'失败'。错误消息为我们提供了一些线索,说明它失败的原因。它通常意味着它试图用布尔数组做一个简单的'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错误。

一般来说,布尔索引或屏蔽在numpyMATLAB中的工作方式相同。 http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#boolean-array-indexing