如何解决Python/Numpy/Boolean 索引:对于数组中的每个 True 值,修改接下来的 2 个元素
array = np.array([5,100,5,5])
我创建了一个带有布尔索引的掩码,如下所示:
mask = (array < 30)
这给出了一个面具
[ True False False False True True False False False True]
我可以使用
获取掩码中True
值的索引
indices = np.where(mask)[0]
这给了
[0 4 5 9]
对于掩码中的每个 True
值,我想将接下来的 2 个元素也修改为 True
。
我可以像这样使用 for
循环来做到这一点:
for i in indices:
mask[i:i+3] = True
在不使用 for
循环的情况下,是否有更 numpythonic 的方法?
所需的掩码输出:
[ True True True False True True True True False True]
这里的主要优先事项是性能。
解决方法
您可以使用 np.flatnonzero
来简化索引的获取。然后你可以为每一个添加 np.arange(3)
:
ind = np.flatnonzero(mask)[:,None] + np.arange(3)
唯一需要注意的是,您的索引可能包含几个越界元素。您可以使用蒙版或 np.clip
:
ind[ind >= mask.size] = mask.size - 1
然后您可以直接应用索引,因为 numpy 允许花式索引的任意维度:
mask[ind] = True
如果有少量涂抹,可以直接涂抹面膜:
mask[1:] |= mask[:-1]
mask[1:] |= mask[:-1]
如果涂抹量是任意的,您显然必须将其置于循环中,但您可以通过步进 2 的幂来优化它。
我称此操作为 mask[1:] |= mask[:-1]
涂抹,因为它会将任意一组 True
元素的大小向右扩大一个,就像您用手指涂抹墨水一样。涂抹任意数量的n
:
s = 1
while s <= n:
mask[s:] |= mask[:-s]
s *= 2
s = n - s // 2
if s:
mask[s:] |= mask[:-s]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。