Среднее значение блока массива numpy 2D

Я хочу найти среднее значение блока 2D-массива в 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 блока размером 2х4, а затем найти среднее значение всех трех блоков (так что форма-это означает 2х4. Первый блок формируется первыми 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]])

Я могу использовать цикл для этого, но я чувствую, что было бы лучше сначала преобразовать этот массив в 3D массив по reshape а затем используйте mean метод на 3D массиве вдоль третьей оси. Это может быть похоже на этот вопрос.

был бы признателен, если кто-то может предоставить мне:

1). Соответствующая команда Pythonic для выполнения среднего блока даже без преобразования в 3D, если такой трюк существует.

2). Если нет соответствующей команды Pythonic для преобразования 2D в 3D.

3). Понимание было бы более эффективно (с точки зрения пространства) сделать это с помощью цикла или с помощью команды выше.

2 ответов


методы 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 требуется только изменить shape и strides атрибуты массива, без необходимости копировать какие-либо фактические данные.

редактировать Чтобы убедиться, что reshaping не копирует массив, а возвращает представление, сделайте reshape как

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

пример docs идет по строкам:

>>> 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 или как по вашему матрица.


Я могу ответить на свой номер 1).

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