【问题标题】:NumPy/Pandas: convert array of "steps" into bool maskNumPy/Pandas:将“步骤”数组转换为布尔掩码
【发布时间】:2016-12-10 22:29:12
【问题描述】:

我有一个这样的数组:

arr = np.array([4, 6, 3, 9, 2, 100, 3, 1, 1, 1, 1])

我想把它转换成这样的布尔数组:

[ T, F, F, F, T,   F, T, F, F, T, T]
# 4, 6, 3, 9, 2, 100, 3, 1, 1, 1, 1

我可以用这样的循环来做到这一点:

mask = np.zeros(len(arr), dtype=bool)
ii = 0
while ii < len(arr):
    mask[ii] = True
    ii += arr[ii]

这是一种间接索引方案,输入中的每个元素都会告诉我们有多少后续元素是无效的。

如何在不使用 Python 循环的情况下做到这一点,这样如果输入数组很大,它会很快?我也很高兴使用 Pandas。

【问题讨论】:

  • 如果我理解正确,这已经很有效(跳转到下一个索引并更改),我无法想象向量操作会对此有所改进......我也怀疑numpy,@ 987654325@ 或 scipy 有一个内在函数,但一个简单的替代方法是用 c/c++ 编写,包装在 ctypes 中并将 numpy 数组传递给您的函数。
  • @EdSmith:循环代码效率不高,原因很简单,它使用 Python 解释器来循环值。如果您有大量数据,这可能需要很长时间。
  • 我的意思是在算法上,如果这是用低级语言编写的,那么在当前形式下它会是最佳的(似乎是不可矢量化的)?在这种情况下,问题是重新占用一些 numpy/pandas 例程比 python 解释器开销更快。
  • @EdSmith:如果我们能在 NumPy 或 Pandas 中找到一组合适的例程,几乎肯定会快得多。这是这个问题的假设——我认为这是一个安全的假设。
  • 我不认为这是可验证的,因为循环的下一步取决于(您执行的内容)上一步。您的下一个索引ii 取决于您在上一步中计算的内容。

标签: pandas numpy vectorization


【解决方案1】:

可能有一些我没有想到的矢量化技巧,但如果你可以使用numba,它非常适合处理这样的问题 - 这个循环现在应该非常快。

import numba

@numba.jit(nopython=True)
def jump_mask(arr):
    mask = np.zeros(len(arr), dtype=np.bool_)
    ii = 0
    while ii < len(arr):
        mask[ii] = True
        ii += arr[ii]
    return mask

【讨论】:

  • 我知道 Numba,但我希望不需要它。通常这些类型的操作可以以某种方式单独使用 NumPy 进行“透视”。
  • 是的,我理解试图避免额外的依赖,但我想不出一种方法来仅使用 numpy/pandas 操作来获得“跳过”,尽管可能。您可能知道,但这在 cython 中也很简单。
猜你喜欢
  • 2014-07-29
  • 1970-01-01
  • 2014-12-22
  • 2017-11-02
  • 2020-05-09
  • 1970-01-01
  • 2021-08-03
  • 1970-01-01
  • 2014-12-20
相关资源
最近更新 更多