【问题标题】:Python/Numpy: Combining boolean masks by row in grouped columns in multidimensional arrayPython / Numpy:在多维数组的分组列中按行组合布尔掩码
【发布时间】:2021-09-12 21:58:28
【问题描述】:

我有一个带有r 行和c 列的 3D 布尔数组(布尔掩码数组的 2D numpy 数组)。在下面的示例中,数组形状为 (3, 6, 2); 3 行 6 列,每列包含 2 个元素。

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

           # If n=2:  |<-   AND   these 2 cols  ->|<-   AND   these 2 cols  ->|<-   AND   these 2 cols  ->|

           # If n=3:  |<-----       AND  these 3 cols    ----->|<-----      AND   these 3 cols     ----->|

我知道我可以将np.all(maskArr, axis=1)and 一起使用all 每行as in previous answer 中的掩码数组,但是我想and 一起使用每行中的布尔数组以n 列为增量。

因此,如果我们从 6 列开始,如上所述,n=2,我想在每 2 列上应用 np.all 的等价物以获得 3 列的最终结果,其中:

  1. 结果数组的第一列等于原始数组AND一起的前 (2) 列的行 - result[:,0] = np.all(maskArr[:,0:1], axis=1)
  2. 结果数组的第二列等于原始数组ANDed 的第二 (2) 列的行。 - result[:,1] = np.all(maskArr[:,2:3], axis=1)
  3. 结果数组的第三列等于原始数组ANDed 的最后 (2) 列的行。 - result[:,2] = np.all(maskArr[:,4:5], axis=1)

有没有办法使用np.all(或其他矢量化方法)来获得这个结果?

预期结果n=2

>>>    np.array([
                     [[True, False], [True, True], [True, True]],
                     [[False, True], [False, True], [True, True]],
                     [[True, False], [True, True], [True, True]],
               ])

注意:我正在使用的数组非常大,因此我正在寻找一种矢量化方法来最大限度地减少对性能的影响。实际的布尔数组可能有数千个元素。

我试过了:

n = 2
c = len(maskArr[0])      ## c = 6  (number of columns)
nResultColumns = int(c / n)   ## nResultColumns = 3

combinedMaskArr = [np.all(maskArr[:,i*n:i*n+n], axis=1) for i in range(nResultColumns)]

这给了我:

>>>  [
         array([[True, False], [False, True], [True, False]]), 
         array([[True, True], [False, True], [True, True]]), 
         array([[True, True], [True, True], [True, True]])
     ]

上面的输出不是预期的格式或值。

关于如何达到预期结果的任何指导或建议?

提前谢谢你。

【问题讨论】:

  • 我不清楚你到底在问什么,抱歉。
  • @orlp 新的介绍有助于澄清吗?
  • 好吧,你说你有一个 2D 数组但你有一个 3D 数组,所以我还是很困惑。
  • 我的错,你是对的。它现在说 3D 数组
  • 问题是你的问题描述没有任何意义。什么是列,什么是行?

标签: python numpy multidimensional-array vectorization


【解决方案1】:

如果我正确理解了您的问题,以下方法有效。

n = 2
cols = mask_arr.shape[1]
chunks = math.ceil(cols / n)
groups = np.array_split(np.swapaxes(mask_arr, 0, 1), chunks)
combined = np.array([np.all(g, axis=0) for g in groups])
result = np.swapaxes(combined, 0, 1)

如果cols 可以被n 整除,我认为这可行:

n = 2
rows, cols = mask_arr.shape[0:2]
result = np.all(mask_arr.reshape(rows, cols // n, n, -1), axis=2)

【讨论】:

  • 谢谢!你的回答确实有效。不过,我不得不问一下 - 你知道是否有一种方法可以在没有列表理解的情况下完全矢量化?
  • @CraigNathan 我想是这样,但前提是列数可以被n整除。
  • 是的,列数总是能被n整除
  • @CraigNathan 那就更简单了,看我更新的答案。
  • @CraigNathan 哦,是的,您可以将其替换为 -1 以自动得出该大小。
猜你喜欢
  • 2021-08-14
  • 1970-01-01
  • 1970-01-01
  • 2021-09-10
  • 2012-02-14
  • 2012-11-16
  • 2013-11-27
  • 2020-04-23
  • 2019-11-04
相关资源
最近更新 更多