Numpy数组条件操作掩码?

3
假设您有一个数组:
a = [ 0,1,0] [-1,2,1] [3,-4,2]
假设您要对每个元素加20:
b = [ 20, 21, 20] [ 19, 22, 21] [ 23, 16, 22]
现在,我想将生成的b添加到原始数组a中,但只在a < 0的情况下,即在索引[0,1][1,2]处,其中a = -1,-4 ,否则获得值0。最终导致如下矩阵:
c = [ 0, 0, 0] [ 18, 0, 0] [ 0, 12, 0]
并假设我想能够将此扩展到任何操作(而不仅仅是添加20),以便无法从矩阵中过滤所有值< 20。因此,我想使用矩阵作为矩阵向量的遮罩,使为零。
我很难找到numpy与python一起执行此类操作的简明示例。我希望您能将我指向正确实现此类方法的地方。
我很困难,无法将其转换为掩码,并仅对保留的值执行操作,最终导致。
提前感谢您的帮助。
5个回答

7

可能是这样的:

(a + b)*(a<0)

只要您对中间数组的数量没有非常严格的要求,那么应该是可行的。

非常优雅的解决方案! - MaxU - stand with Ukraine
这是最优雅的解决方案。我无法想象有人能有更简洁的方法。非常干净地执行了。谢谢。 - andor kesselman

1
你可以通过布尔索引广播的结合来实现这一点。下面是一个工作示例,
import numpy as np
a = np.array([[ 0,1,0],[-1,2,1],[3,-4,2]])
b = a+20
c = np.zeros(a.shape)
c[a<0] = b[a<0] + a[a<0]

这个代码会输出c

array([[  0.,   0.,   0.],
       [ 18.,   0.,   0.],
       [  0.,  12.,   0.]])

上面代码片段中唯一重要的一行是最后一行。因为abc的条目都对齐,所以我们可以说我们只想要a<0的相应索引的c被分配到ba的条目之和,其中a<0

这个不错,但不如Thomas的解决方案优雅。感谢提供的链接和尝试。 - andor kesselman

1
这是另一种获得相同结果的方法:
c = np.where(a < 0, a + b, 0)

尽管这比Thomas Baruchel的解决方案稍微冗长一些,但我发现方法签名类似于三元操作符(a < 0 ? a + b : 0),这使我更容易立即理解它在做什么。此外,这仍然是一个一行代码的解决方案,在我看来足够优雅。
参考: numpy.where

0
也许不是最简洁的解决方案,但这样怎么样?
def my_mask(a, b, threshold=0):
    c = numpy.zeros(a.shape)
    idx = np.where(a < threshold)
    for ii in idx:
        c[ii[1], ii[0]] = a[ii[1], ii[0]] + b[ii[1], ii[0]]
    return c

2
在处理NumPy数组时,应该尽量避免使用for循环,除非所需操作无法向量化。 - Will Barnes

0

使用numpy.zeros_like函数的解决方案:

import numpy as np

# the initial array
a = [[ 0,1,0],
     [-1,2,1],
     [3,-4,2]]

a = np.array(a)
b = a + 20                         # after adding 20 to each element
c = np.zeros_like(a)               # resulting matrix (filled with zeros by default)
neg = a < 0                        # indeces of negative values
c[neg] = b[neg] + a[neg]           # overriding the needed elements

print(c)

输出:
[[ 0  0  0]
 [18  0  0]
 [ 0 12  0]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接