【问题标题】:How to properly mask a numpy 2D array?如何正确屏蔽 numpy 二维数组?
【发布时间】:2016-11-06 17:33:14
【问题描述】:

假设我有一个二维坐标数组,看起来像

x = array([[1,2],[2,3],[3,4]])

到目前为止,在我的工作中,我生成了一个面具,最终看起来像

mask = [False,False,True]

当我尝试在 2D 坐标向量上使用此遮罩时,我收到错误

newX = np.ma.compressed(np.ma.masked_array(x,mask))

>>>numpy.ma.core.MaskError: Mask and data not compatible: data size 
   is 6, mask size is 3.`

我想这是有道理的。所以我尝试简单地使用以下掩码:

mask2 = np.column_stack((mask,mask))
newX = np.ma.compressed(np.ma.masked_array(x,mask2))

我得到的很接近:

>>>array([1,2,2,3])

达到我的期望(和想要):

>>>array([[1,2],[2,3]])

一定有更简单的方法来做到这一点?

【问题讨论】:

    标签: python numpy matrix mask masked-array


    【解决方案1】:

    这是你要找的吗?

    import numpy as np
    x[~np.array(mask)]
    # array([[1, 2],
    #        [2, 3]])
    

    或来自numpy masked array

    newX = np.ma.array(x, mask = np.column_stack((mask, mask)))
    newX
    
    # masked_array(data =
    #  [[1 2]
    #  [2 3]
    #  [-- --]],
    #              mask =
    #  [[False False]
    #  [False False]
    #  [ True  True]],
    #        fill_value = 999999)
    

    【讨论】:

    • 啊,我明白了,所以我尝试的方法确实有效,但我无法压缩它。嗯。有没有办法在不丢失数组维度的情况下删除数组的屏蔽元素? np.ma.compressed() 两者都有。
    • 蒙面数组我也不多说,大概和你一样的水平。只是想让它工作。好吧,如果您尝试删除元素,我认为逻辑索引不是一个坏方法。
    【解决方案2】:

    您的x 是 3x2:

    In [379]: x
    Out[379]: 
    array([[1, 2],
           [2, 3],
           [3, 4]])
    

    制作一个 3 元素布尔掩码:

    In [380]: rowmask=np.array([False,False,True])
    

    这可用于选择为真或为假的行。在这两种情况下,结果都是 2d:

    In [381]: x[rowmask,:]
    Out[381]: array([[3, 4]])
    
    In [382]: x[~rowmask,:]
    Out[382]: 
    array([[1, 2],
           [2, 3]])
    

    这没有使用 MaskedArray 子类。要制作这样的数组,我们需要一个形状与x 匹配的掩码。没有规定只屏蔽一个维度。

    In [393]: xmask=np.stack((rowmask,rowmask),-1)  # column stack
    
    In [394]: xmask
    Out[394]: 
    array([[False, False],
           [False, False],
           [ True,  True]], dtype=bool)
    
    In [395]: np.ma.MaskedArray(x,xmask)
    Out[395]: 
    masked_array(data =
     [[1 2]
     [2 3]
     [-- --]],
                 mask =
     [[False False]
     [False False]
     [ True  True]],
           fill_value = 999999)
    

    应用compressed 会产生一个散列数组:array([1, 2, 2, 3])

    由于屏蔽是逐个元素的,因此它可以屏蔽第 1 行中的一个元素,第 2 行中的 2 个等。所以一般compressing,删除被屏蔽的元素不会产生二维数组。扁平形式是唯一的通用选择。

    np.ma 在屏蔽值分散时最有意义。如果要选择或取消选择整行或整列,它没有多大价值。

    ================

    下面是比较典型的掩码数组:

    In [403]: np.ma.masked_inside(x,2,3)
    Out[403]: 
    masked_array(data =
     [[1 --]
     [-- --]
     [-- 4]],
                 mask =
     [[False  True]
     [ True  True]
     [ True False]],
           fill_value = 999999)
    
    In [404]: np.ma.masked_equal(x,2)
    Out[404]: 
    masked_array(data =
     [[1 --]
     [-- 3]
     [3 4]],
                 mask =
     [[False  True]
     [ True False]
     [False False]],
           fill_value = 2)
    
    In [406]: np.ma.masked_outside(x,2,3)
    Out[406]: 
    masked_array(data =
     [[-- 2]
     [2 3]
     [3 --]],
                 mask =
     [[ True False]
     [False False]
     [False  True]],
           fill_value = 999999)
    

    【讨论】:

      【解决方案3】:

      有了np.where,你可以做各种各样的事情:

      x_maskd = np.where(mask, x, 0)
      

      【讨论】:

        【解决方案4】:

        由于这些解决方案都不适合我,我想写下解决方案的作用,也许它对其他人有用。我使用 python 3.x 并处理了两个 3D 数组。一个,我称之为data_3D 包含大脑扫描中记录的浮点值,另一个,template_3D 包含表示大脑区域的整数。我想从data_3D 中选择对应于整数region_code 的值,根据template_3D

        my_mask = np.in1d(template_3D, region_code).reshape(template_3D.shape)
        data_3D_masked = data_3D[my_mask]
        

        这给了我一个只有相关录音的一维数组。

        【讨论】:

          【解决方案5】:

          在您的最后一个示例中,问题不在于掩码。这是您对compressed 的使用。来自compressed的文档字符串:

          Return all the non-masked data as a 1-D array.
          

          所以compressed 将非屏蔽值展平为一维数组。 (必须如此,因为无法保证压缩后的数据具有 n 维结构。)

          在压缩之前先看一下掩码数组:

          In [8]: np.ma.masked_array(x, mask2)
          
          Out[8]: 
          masked_array(data =
           [[1 2]
           [2 3]
           [-- --]],
                       mask =
           [[False False]
           [False False]
           [ True  True]],
                 fill_value = 999999)
          

          【讨论】:

          • 你是对的,在我压缩之前它是正确的。我将阅读文档以了解在保留数组维度的同时删除被屏蔽元素的方法。谢谢
          • 如果我理解你想要做什么,@Psidom 的第一个建议看起来很合理。特别是,您可能不需要掩码数组。只需使用布尔数组索引一个常规数组即可。
          【解决方案6】:

          如果你有

          A =  [[  8.   0. 165.  22. 164.  47. 184. 185.]
                [  0.   6. -74. -27.  63.  49. -46. -48.]
                [165. -74.   0.   0.   0.   0.   0.   0.]
                [ 22. -27.   0.   0.   0.   0.   0.   0.]
                [164.  63.   0.   0.   0.   0.   0.   0.]
                [ 47.  49.   0.   0.   0.   0.   0.   0.]
                [184. -46.   0.   0.   0.   0.   0.   0.]
                [185. -48.   0.   0.   0.   0.   0.   0.]]
          

          你的面具是

          mask = np.array([True, True, True, False, True, False, True, False])
          

          那么你的蒙面 A 就变成了

          A[mask, :][:, mask] = [[  8.   0. 165. 164. 184.]
                                 [  0.   6. -74.  63. -46.]
                                 [165. -74.   0.   0.   0.]
                                 [164.  63.   0.   0.   0.]
                                 [184. -46.   0.   0.   0.]]
          

          【讨论】:

            猜你喜欢
            • 2021-12-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-05-16
            • 2021-01-14
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多