NumPy 2D数组的块平均值

9

我希望在NumPy中找到一个二维数组的块平均值。为了简单起见,让我们假设数组如下:

array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]])

我希望将这个数组分成3个大小为2x4的块,并找到所有三个块的平均值(以便平均值的形状为2x4)。第一个块由前4列组成,下一个块由接下来的4列组成,依此类推。所以我的块如下:

array([[0, 1, 2, 3],
       [12, 13, 14, 15]])

array([[ 4,  5,  6,  7],
       [16, 17, 18, 19]])

array([[ 8,  9, 10, 11],
       [20, 21, 22, 23]])

我可以使用循环来完成这个任务,但我感觉首先将该数组通过reshape转换为3D数组,然后沿第三轴使用mean方法对3D数组进行操作会更好。 这可能类似于这个问题
如果有这样的技巧存在,那么希望有人能够提供一个适合的Python命令,以完成均值计算而无需将其转换为3D数组。
如果没有,也希望有人能够提供一个适当的Python命令,以将2D转换为3D。
请提供您的见解,无论是使用循环还是使用上述命令,哪种方法在空间方面更有效。

2
你所链接的问题,或者说实际上是答案,是我见过的最酷的numpy代码之一。 - Jaime
2个回答

5

NumPy的方法几乎总是比Python循环更快,因此我将跳过你的1。

至于2,在这种特殊情况下,以下方法可以使用:

a = np.array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11],
              [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]])
a = a.reshape(2, 3, 4)
>>> a
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])
>>> np.mean(a, axis=1)
array([[  4.,   5.,   6.,   7.],
       [ 16.,  17.,  18.,  19.]])

技巧在于reshape。对于想要n列块的一般情况,以下是一个选项。
a = a.reshape((a.shape[0], -1, n))

您的3个担忧大部分是不必要的。 reshape 返回原始数组的视图,而不是副本,因此将其转换为3D仅需要更改数组的 shapestrides 属性,而无需复制任何实际数据。 编辑 为确保重新整形不会复制数组,而是返回视图,请按以下方式进行重新整形
a.shape = a = a.reshape((a.shape[0], -1, n))

文档中的示例大致如下:

>>> a = np.arange(12).reshape(3,4)
>>> b = a.T
>>> b.shape = (12,)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: incompatible shape for a non-contiguous array

一般而言,如果您对数组进行了转置 (transpose)轴旋转 (rollaxis)轴交换 (swapaxes)等操作,则可能会出现问题。


谢谢!这很酷!我提到第三点的原因是因为numpy.reshape文档提到返回值可能是一个副本,而不是视图。 - Nik

-1

我可以回答你的第一点)。

vstack([mean(a[:,4*i:4*(i+1)],axis=1) for i in range(3)]).T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接