【问题标题】:How to mask rows of a 2D numpy matrix by values in 1D list?如何通过 1D 列表中的值屏蔽 2D numpy 矩阵的行?
【发布时间】:2021-08-30 20:22:01
【问题描述】:

我有一个 2D numpy 数组,如下所示:

a = np.array([[0, 1, 2, 3, 4],
              [0, 1, 2, 3, 4],
              [0, 1, 2, 3, 4],
              [0, 1, 2, 3, 4],
              [0, 1, 2, 3, 4]])

还有一个如下所示的一维列表:

b = [4, 3, 2, 3, 4]

我想根据给定行中的哪些值小于我的一维列表 (b) 中的相应值来屏蔽我的二维数组 (a)。例如,根据该行中的哪些值小于 b[0] 处的值,将屏蔽 a[0] 行;与行 a[1] 和 b[1] 处的值相同,依此类推...

我希望得到的是一个二维布尔数组:

mask_bools = [[True, True, True, True, False],
              [True, True, True, False, False],
              [True, True, False, False, False],
              [True, True, True, False, False],
              [True, True, True, True, False]]

我有一个愚蠢的方法来实现这个循环:

mask_bools = []
for i in range(len(b)):
    mask_bools.append(np.ma.masked_less(a[i], b[i]).mask)
mask_bools = np.array(mask_bools)

但我觉得必须有更好/更快的方法来做到这一点,从而更好地利用 numpy 功能。有任何想法吗?谢谢!

【问题讨论】:

    标签: python arrays numpy masking


    【解决方案1】:

    您可以使用np.vectorize 来实现此目的。创建一个函数,比较适当索引处的值并返回一个布尔值。

    它基本上和你现在做的一样,但正如你所说,这只是 NumPy 实现。

    【讨论】:

      【解决方案2】:

      你可以试试这个:

      import numpy as np
      a = np.array([[0, 1, 2, 3, 4],
                    [0, 1, 2, 3, 4],
                    [0, 1, 2, 3, 4],
                    [0, 1, 2, 3, 4],
                    [0, 1, 2, 3, 4]])
      
      
      b = np.array([[4, 3, 2, 3, 4],]*len(a)).T
      
      a < b
      
      array([[ True,  True,  True,  True, False],
             [ True,  True,  True, False, False],
             [ True,  True, False, False, False],
             [ True,  True,  True, False, False],
             [ True,  True,  True,  True, False]])
      

      为了更高效的使用:

      b = np.tile(np.array([[4, 3, 2, 3, 4]]).transpose(), (1, len(a)))
      

      然而,这更难阅读。

      【讨论】:

        【解决方案3】:

        试试broadcasting小于:

        a < b[:, None]
        
        [[ True  True  True  True False]
         [ True  True  True False False]
         [ True  True False False False]
         [ True  True  True False False]
         [ True  True  True  True False]]
        
        import numpy as np
        
        a = np.array([[0, 1, 2, 3, 4],
                      [0, 1, 2, 3, 4],
                      [0, 1, 2, 3, 4],
                      [0, 1, 2, 3, 4],
                      [0, 1, 2, 3, 4]])
        
        b = np.array([4, 3, 2, 3, 4])
        
        c = a < b[:, None]
        
        # Test equality with expected output
        mask_bools = np.array([[True, True, True, True, False],
                               [True, True, True, False, False],
                               [True, True, False, False, False],
                               [True, True, True, False, False],
                               [True, True, True, True, False]])
        
        print((c == mask_bools).all().all())  # True
        

        【讨论】:

          猜你喜欢
          • 2016-08-12
          • 2011-06-05
          • 1970-01-01
          • 2019-10-20
          • 1970-01-01
          • 1970-01-01
          • 2014-01-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多