【问题标题】:Numpy Array Conditional Operation Mask?Numpy 数组条件操作掩码?
【发布时间】:2020-11-20 10:53:09
【问题描述】:

假设你有一个数组:

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] 18 = 19 (from b) + -1 (from a) 12 = 16 (from b) + -4 (from a)

并假设我希望能够将其扩展到任何操作(不仅仅是添加 20),这样您就不能只从矩阵 c 中过滤所有 a作为矩阵c的掩码,将i, j归零,其中a[i,j] < 0

我很难找到一个简洁的例子来说明如何在 numpy 中使用 python 做到这一点。我希望您能指导我正确实施这种方法。

我正在努力将它变成一个掩码并且只对保留的值执行操作,最终导致c

提前感谢您的帮助。

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    大概是这样的:

    (a + b)*(a<0)
    

    应该可以工作,除非您对中间数组的数量有非常严格的要求。

    【讨论】:

    • 非常优雅的解决方案!
    • 这是最优雅的解决方案。我无法想象有人有更干净的方法。执行得非常干净。谢谢。
    【解决方案2】:

    您可以通过boolean indexingbroadcasting 的组合来完成此操作。下面的工作示例,

    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.]])
    

    上面代码sn-p中唯一重要的一行是最后一行。因为abc 的条目都是对齐的,所以我们可以说我们只希望c 的相应索引被分配给a&lt;0 中的条目总和和a,其中a&lt;0

    【讨论】:

    • 这很好,但不如 Thomas 的解决方案优雅。感谢您的链接和尝试。
    【解决方案3】:

    这是获得相同结果的另一种方法:

    c = np.where(a < 0, a + b, 0)
    

    虽然这比Thomas Baruchel's solution略冗长,但我发现方法签名类似于三元运算(a &lt; 0 ? a + b : 0),这让我更容易立即理解它在做什么。此外,在我看来,这仍然是一个单行代码,足以使其优雅。

    参考:numpy.where

    【讨论】:

      【解决方案4】:

      也许不是最干净的解决方案,但是这个怎么样?:

      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
      

      【讨论】:

      • 在处理 NumPy 数组时,应该真正避免 For 循环,除非所需的操作无法向量化。
      【解决方案5】:

      使用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]]
      

      【讨论】:

        猜你喜欢
        • 2021-04-21
        • 2014-03-03
        • 2018-04-09
        • 2017-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多