【问题标题】:Numpy 2-D array boolean maskingNumpy 2-D 数组布尔掩码
【发布时间】:2018-08-26 00:57:45
【问题描述】:

numpy tutorial 中的一个例子我看不懂。

a = np.arange(12).reshape(3,4)
b1 = np.array([False, True, True])
b2 = np.array([True, False, True, False])

那为什么a[b1,b2] 会返回array([4, 10])?它不应该返回array([[4, 6], [8, 10]])吗?

感谢任何详细的解释!

【问题讨论】:

    标签: arrays numpy indexing


    【解决方案1】:

    在 2D numpy 数组上应用 general 布尔 2D 掩码的另一种方法如下:

    使用矩阵元素乘法:

    import numpy as np
    
    n = 100
    mask = np.identity(n)
    data = np.random.rand(n,n)
    
    data_masked = data * mask
    

    在这个随机示例中,您只保留对角线上的元素。 掩码可以是任何 n × n 矩阵。

    【讨论】:

    • 这仍然会在矩阵中留下 0,因此它不适用于均值计算。
    • 什么意思?你的目标是什么?这只是一个关于如何应用 2d 遮罩的示例。
    • 公平我的评论超出了问题的范围,所以可能不是这个地方。我的观点是,将 2d 数组乘以 2d 掩码实际上并没有将数组子集/用 np.nan 替换不需要的元素。因此,如果您可以将 0 视为空值,则此方法有效,例如如果你是求和但不是平均。
    • OP 询问了其他问题。但是,您可以在 0.5 秒内实现您所需要的:data[mask.astype(bool)].mean()
    • 太棒了,太棒了。谢谢!
    【解决方案2】:

    当你用多个数组索引一个数组时,它会用索引数组中的元素对来索引

    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> b1
    array([False,  True,  True], dtype=bool)
    >>> b2
    array([ True, False,  True, False], dtype=bool)
    >>> a[b1, b2]
    array([ 4, 10])
    

    注意这相当于:

    >>> a[(1, 2), (0, 2)]
    array([ 4, 10])
    

    a[1, 0]a[2, 2] 的元素

    >>> a[1, 0]
    4
    >>> a[2, 2]
    10
    

    由于这种成对行为,您通常不能使用单独的长度数组进行索引(它们必须能够广播)。所以这个例子有点意外,因为两个索引数组都有两个索引,它们是True;例如,如果一个有三个 True 值,你会得到一个错误:

    >>> b3 = np.array([True, True, True, False])
    >>> a[b1, b3]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (3,)
    

    所以这特别是让您知道索引数组必须能够一起广播(以便它可以以一种智能的方式将索引组合在一起;例如,如果一个索引数组只有一个值,那将被重复与另一个索引数组中的每个值)。

    要获得您期望的结果,您可以单独索引结果:

    >>> a[b1][:, b2]
    array([[ 4,  6],
           [ 8, 10]])
    

    否则,您也可以将索引数组转换为与a 形状相同的二维数组,但请注意,如果这样做,结果将是一个线性数组(因为可以拉出任意数量的元素,当然可能不是方形的):

    >>> a[np.outer(b1, b2)]
    array([ 4,  6,  8, 10])
    

    【讨论】:

      【解决方案3】:

      第一个数组的 true 索引是

      >>> i = np.where(b1)
      >>> i 
      array([1,2])
      

      对于第二个数组,它们是

      >>> j = np.where(b2)
      >>> j
      array([0,1])
      

      结合使用这些索引掩码,

      >>> a[i,j]
      array([4, 10])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-23
        • 1970-01-01
        • 2013-11-27
        • 2020-05-09
        • 2016-12-10
        • 2021-08-14
        • 2019-11-04
        • 2020-07-19
        相关资源
        最近更新 更多