【问题标题】:simpler way to filter out nan or invalid's in Python array or a numpy array?在 Python 数组或 numpy 数组中过滤掉 nan 或 invalid 的更简单方法?
【发布时间】:2015-04-03 07:45:01
【问题描述】:

我有 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 中失败 ,heights 仍然是一个 numpy 数组。我回去做...

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

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

/编辑

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

毛。我已经使用 python 2-3 个月了,但我仍然没有真正了解如何有效和简单地使用 numpy 屏蔽系统。我来自大量使用 matlab,其中“掩码”将是一组相同形状/大小的布尔值。例如

heights = heights(~isnan(heights));

或者……

heights(isnan(heights)) = [];

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

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

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

【问题讨论】:

标签: python arrays matlab python-2.7 numpy


【解决方案1】:

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

【讨论】:

  • 我其实不知道numpy支持~。我一直在使用np.logical_not 哈哈。感谢您的提示!
  • 数组 OR 或数组 AND 怎么样
  • @user27886 - 使用 &amp;| 就足够了。我知道。
  • @user27886 - &amp;| 仅适用于 bool 类型 numpy 数组。您可能想要使用np.logical_andnp.logical_not。他们可以处理任何numpy 数组。
  • 可能还值得一提np.isfinite,它将过滤掉NaN、Inf等。对于OP的情况heights[np.isfinite(heights)]。当然,如果您想将 +/-Inf 保留为有效值,您将需要 ~np.isnan(data) 而不是 isfinite
【解决方案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 有一个 2 面布尔比较,适用于单个值。 numpy 没有。没有(),它首先执行heights &amp; heights,然后尝试应用单值Python操作,导致ambiguous boolean错误。

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

【讨论】:

    猜你喜欢
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    • 2021-07-05
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-24
    相关资源
    最近更新 更多