【问题标题】:numpy: Creating a binary mask for a float array without allocating intermediate arraysnumpy:为浮点数组创建二进制掩码而不分配中间数组
【发布时间】:2020-12-08 11:19:36
【问题描述】:

我有两个相同形状的 numpy 浮点数组:datamask。我想根据data 中的值填充mask 的值。当data 中某个元素的值等于“可接受值”之一(见下文)时,mask 中的对应项应设置为 1.0,否则应设置为 0.0。

有两种可能的情况:

  1. 可接受的值都是有限数
  2. 可接受的值是除 0.0 之外的所有有限数

如何在没有任何额外数组分配的情况下实现上述目标?对于第一种情况,我可以使用 numpy.isfiniteout 参数。但是第二种情况呢? numpy.where 不能使用,因为它需要创建一个中间索引数组。我能想到的唯一解决方案是将 numpy 数组传递给 C 并在那里执行。但是,我想知道是否也有纯 numpy 解决方案。

谢谢。

【问题讨论】:

  • 你需要的不是布尔掩码吗?
  • 理想情况下,mask 数组也应该是一个浮点数组(刚刚在我的帖子中澄清过)。不过,对于不同类型的 mask 数组,我预计解决方案不会有很大差异。
  • 创建数组真的是算法的瓶颈吗?
  • 为什么?您是遇到内存错误,还是只是希望节省时间?

标签: python arrays numpy


【解决方案1】:

也许使用np.isfinite 函数的where 参数过滤掉等于0 的元素会达到你想要的效果?然而,它比使用额外布尔数组的其他选项慢。

import numpy as np

# Dummy data
data = np.tile([0,np.inf,2,3,4,5], 10000000).astype(float)
mask = np.zeros_like(data, dtype = float)

# First scenario
np.isfinite(data, out = mask)

# Second scenario 
mask = np.zeros_like(data, dtype = float)
np.isfinite(data, out = mask, where = data != 0)
# Faster method using intermediate boolean arrays
np.bitwise_and(np.isfinite(data), data != 0, out = mask)

【讨论】:

  • 这两种方法都会创建一个临时的data != 0 数组。
  • 如果maskbool dtype,所有方法都更快。
  • @hpaulj 你当然是对的。不过,他为问题中的掩码数组指定了 float dtype。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-29
  • 2017-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多