【问题标题】:Delete all elements in an array corresponding to Boolean mask删除与布尔掩码对应的数组中的所有元素
【发布时间】:2018-01-26 15:11:59
【问题描述】:

我有一个作为二维 numpy 数组(布尔数组)存在的布尔掩码

array([[ True,  True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True,  True],
       [False, False, False, False, False, False, False],
       [False, False, False, False, False, False, False],
       [False, False, False, False, False, False, False]], dtype=bool)

我还有一个单独的二维 numpy 值数组,与布尔掩码(值数组)具有相同的维度

array([[ 19.189 ,  23.2535,  23.1555,  23.4655,  22.6795,  20.3295,  19.7005],
       [ 20.688 ,  20.537 ,  23.8465,  21.2265,  24.5805,  25.842 ,  23.198 ],
       [ 22.418 ,  21.0115,  21.0355,  20.217 ,  24.1275,  24.4595,  21.981 ],
       [ 21.156 ,  18.6195,  23.299 ,  22.5535,  23.2305,  28.749 ,  21.0245],
       [ 21.7495,  19.614 ,  20.3025,  21.706 ,  22.853 ,  19.623 ,  16.7415],
       [ 20.9715,  21.9505,  21.1895,  21.471 ,  21.0445,  21.096 ,  19.3295],
       [ 24.3815,  26.2095,  25.3595,  22.9985,  21.586 ,  23.796 ,  20.375 ]])

我想做的是从值数组中删除布尔区域中相同位置等于False 的所有元素。是否有捷径可寻?

此示例所需的输出是:

array([[ 19.189 ,  23.2535,  23.1555,  23.4655,  22.6795,  20.3295,  19.7005],
       [ 20.688 ,  20.537 ,  23.8465,  21.2265,  24.5805,  25.842 ,  23.198 ],
       [ 22.418 ,  21.0115,  21.0355,  20.217 ,  24.1275,  24.4595,  21.981 ],
       [ 21.156 ,  18.6195,  23.299 ,  22.5535,  23.2305,  28.749 ,  21.0245]])

在这个特定示例中,所有False 值都存在于布尔数组的末尾,但情况并非总是如此,它们可以随机分布。因此,我需要一种从值数组中删除布尔数组中对应掩码值等于False 的任何元素的方法

【问题讨论】:

  • 整行是真还是假?还是会有混合的?
  • 如果我的回答有帮助,您可以mark it accepted 或告诉我出了什么问题,以便我解决。
  • arr[mask] 做出这样的选择。结果将是 1d,因为通常这样的掩码可以选择每行不同数量的值。在某些情况下,您可能能够将结果重塑为有意义的二维数组。

标签: python arrays numpy multidimensional-array slice


【解决方案1】:

假设您的掩码将包含全部为True 或全部为False 的行,那么您可以使用mask.all(axis=1) 和索引:

In [116]: x
Out[116]: 
array([[ 1.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  1.]])

In [117]: x[mask.all(axis=1)]
Out[117]: 
array([[ 1.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  1.,  0.,  0.,  0.]])

【讨论】:

    【解决方案2】:

    对于大多数目的,您可以简单地创建一个MaskedArray,其行为就像这些被“删除”一样,它还允许从列/行中“删除”单个元素,同时保持维度相同:

    import numpy as np
    arr = np.array([[ 19.189 , 23.2535, 23.1555, 23.4655, 22.6795, 20.3295, 19.7005],
                    [ 20.688 , 20.537 , 23.8465, 21.2265, 24.5805, 25.842 , 23.198 ],
                    [ 22.418 , 21.0115, 21.0355, 20.217 , 24.1275, 24.4595, 21.981 ],
                    [ 21.156 , 18.6195, 23.299 , 22.5535, 23.2305, 28.749 , 21.0245],
                    [ 21.7495, 19.614 , 20.3025, 21.706 , 22.853 , 19.623 , 16.7415],
                    [ 20.9715, 21.9505, 21.1895, 21.471 , 21.0445, 21.096 , 19.3295],
                    [ 24.3815, 26.2095, 25.3595, 22.9985, 21.586 , 23.796 , 20.375 ]])
    mask = np.array([[ True,  True,  True,  True,  True,  True,  True],
                     [ True,  True,  True,  True,  True,  True,  True],
                     [ True,  True,  True,  True,  True,  True,  True],
                     [ True,  True,  True,  True,  True,  True,  True],
                     [False, False, False, False, False, False, False],
                     [False, False, False, False, False, False, False],
                     [False, False, False, False, False, False, False]])
    marr = np.ma.MaskedArray(arr, mask=~mask)
    marr
    

    给予:

    masked_array(data =
     [[19.189 23.2535 23.1555 23.4655 22.6795 20.3295 19.7005]
     [20.688 20.537 23.8465 21.2265 24.5805 25.842 23.198]
     [22.418 21.0115 21.0355 20.217 24.1275 24.4595 21.981]
     [21.156 18.6195 23.299 22.5535 23.2305 28.749 21.0245]
     [-- -- -- -- -- -- --]
     [-- -- -- -- -- -- --]
     [-- -- -- -- -- -- --]],
                 mask =
     [[False False False False False False False]
     [False False False False False False False]
     [False False False False False False False]
     [False False False False False False False]
     [ True  True  True  True  True  True  True]
     [ True  True  True  True  True  True  True]
     [ True  True  True  True  True  True  True]],
           fill_value = 1e+20)
    

    在这种情况下,也可以只压缩包含至少一个带有np.ma.compress_rows 的掩码元素的所有行:

    >>> np.ma.compress_rows(marr)
    array([[ 19.189 ,  23.2535,  23.1555,  23.4655,  22.6795,  20.3295,  19.7005],
           [ 20.688 ,  20.537 ,  23.8465,  21.2265,  24.5805,  25.842 ,  23.198 ],
           [ 22.418 ,  21.0115,  21.0355,  20.217 ,  24.1275,  24.4595,  21.981 ],
           [ 21.156 ,  18.6195,  23.299 ,  22.5535,  23.2305,  28.749 ,  21.0245]])
    

    【讨论】:

      【解决方案3】:

      为了说明我的评论:

      In [33]: arr = np.arange(12).reshape(3,4)
      In [34]: mask = ((arr+1)%3)>0
      In [35]: mask
      Out[35]: 
      array([[ True,  True, False,  True],
             [ True, False,  True,  True],
             [False,  True,  True, False]], dtype=bool)
      

      arr[mask] 是 1d,因为通常这个选择不会返回一个整洁的 2d 数组。

      In [36]: arr[mask]
      Out[36]: array([ 0,  1,  3,  4,  6,  7,  9, 10])
      

      我们可以通过掩码数组解决方案清楚地看到这一点

      In [37]: marr = np.ma.MaskedArray(arr,mask=~mask)
      In [38]: marr
      Out[38]: 
      masked_array(data =
       [[0 1 -- 3]
       [4 -- 6 7]
       [-- 9 10 --]],
                   mask =
       [[False False  True False]
       [False  True False False]
       [ True False False  True]],
             fill_value = 999999)
      

      ma压缩后返回一维数组

      In [39]: marr.compressed()
      Out[39]: array([ 0,  1,  3,  4,  6,  7,  9, 10])
      

      使用 8 个术语,我可以将其重塑为 (4,2),但不涉及 3。

      您可以使用anyall 的各种组合来屏蔽整行或整列。

      【讨论】:

        猜你喜欢
        • 2021-03-09
        • 2013-11-27
        • 2018-10-02
        • 1970-01-01
        • 1970-01-01
        • 2020-11-07
        • 1970-01-01
        • 2020-08-29
        • 2016-11-22
        相关资源
        最近更新 更多