Block mean of numpy 2D array

荒凉一梦 提交于 2019-12-10 04:15:07

问题


I want to find block mean of a 2D array in NumPy. For simplicity, let us assume that the array is as follows:

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]])

I want to divide this array into 3 blocks of size 2x4, and then find the mean of all three blocks (so that the shape of the mean is 2x4. The first block is formed by the first 4 columns, the next one by the next 4 columns and so on. So my blocks are:

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]])

I can use a loop to do this but I get a feel that it would be better to first convert this array into a 3D array by reshape and then use the mean method on the 3D array along the third axis. This could be similar to this question.

Would appreciate if someone can provide me with:

1). An appropriate Pythonic command to do the block mean without even converting to 3D, if such a trick exists.

2). If not an appropriate Pythonic command to do the 2D to 3D conversion.

3). An insight whether it would be more efficient (in terms of space) to do it using a loop or by using the command above.


回答1:


Numpy methods are going to beat python loops almost always, so I am going to skip your 1.

As for 2, in this particular case the following works:

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.]])

The trick is in the reshape. For a general case where you want blocks of n columns, the following is an option

a = a.reshape((a.shape[0], -1, n))

Your concerns in 3 are mostly unwarranted. reshape returns a view of the original array, not a copy, so the conversion to 3D only requires altering the shape and strides attributes of the array, without having to copy any of the actual data.

EDIT To be sure that reshaping does not copy the array, but returns a view, do the reshape as

a.shape = a = a.reshape((a.shape[0], -1, n))

The example in the docs goes along the lines of:

>>> 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

And in general there are only problems if you have been doing transpose, rollaxis, swapaxes or the like on your array.




回答2:


I can answer ur number 1).

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


来源:https://stackoverflow.com/questions/14229029/block-mean-of-numpy-2d-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!