Python/Numpy/Boolean 索引:对于数组中的每个 True 值,修改接下来的 2 个元素
Python/Numpy/Boolean Indexing: For each True value in array, modify the next 2 elements
我有一个 numpy 数组
array = np.array([5,100,100,100,5,5,100,100,100,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)
唯一需要注意的是您的索引可能包含几个越界元素。你可以 trim 他们带着面具或 np.clip
:
ind[ind >= mask.size] = mask.size - 1
然后您可以直接应用索引,因为 numpy 允许花式索引的任意维度:
mask[ind] = True
如果要做小涂抹,可以直接涂抹面膜:
mask[1:] |= mask[:-1]
mask[1:] |= mask[:-1]
如果涂抹量是任意的,你显然必须把它放在一个循环中,但你可以通过以二的幂步进来优化它。
我称操作 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]
我有一个 numpy 数组
array = np.array([5,100,100,100,5,5,100,100,100,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)
唯一需要注意的是您的索引可能包含几个越界元素。你可以 trim 他们带着面具或 np.clip
:
ind[ind >= mask.size] = mask.size - 1
然后您可以直接应用索引,因为 numpy 允许花式索引的任意维度:
mask[ind] = True
如果要做小涂抹,可以直接涂抹面膜:
mask[1:] |= mask[:-1]
mask[1:] |= mask[:-1]
如果涂抹量是任意的,你显然必须把它放在一个循环中,但你可以通过以二的幂步进来优化它。
我称操作 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]