2012-05-09 1 views
8

У меня есть ось Ось 3, элементы которой 3-мерные. Я хотел бы усреднить их и вернуть ту же форму массива. Нормальная средняя функция удаляет 3 размеры и заменить его в среднем (как и ожидалось):средняя матрица numpy, но сохраняю форму

a = np.array([[[0.1, 0.2, 0.3], [0.2, 0.3, 0.4]], 
       [[0.4, 0.4, 0.4], [0.7, 0.6, 0.8]]], np.float32) 

b = np.average(a, axis=2) 
# b = [[0.2, 0.3], 
#  [0.4, 0.7]] 

Результат требуется:

# b = [[[0.2, 0.2, 0.2], [0.3, 0.3, 0.3]], 
#  [[0.4, 0.4, 0.4], [0.7, 0.7, 0.7]]] 

Вы можете сделать это элегантно, или я просто итерировать над массивом в Python (который будет намного медленнее по сравнению с мощной функцией Numpy).

Можете ли вы установить аргумент Dtype для функции np.mean в 1D-массив?

Спасибо.

+2

большой поклонник того, что вы хотите видеть в этом вопросе. – lukecampbell

+0

В большинстве случаев я могу себе представить, что трансляция сделает это, не требуя 3d-массива. – tillsten

ответ

3
>>> import numpy as np 
>>> a = np.array([[[0.1, 0.2, 0.3], [0.2, 0.3, 0.4]], 
...    [[0.4, 0.4, 0.4], [0.7, 0.6, 0.8]]], np.float32) 
>>> b = np.average(a, axis=2) 
>>> b 
array([[ 0.2  , 0.29999998], 
     [ 0.40000001, 0.69999999]], dtype=float32) 
>>> c = np.dstack((b, b, b)) 
>>> c 
array([[[ 0.2  , 0.2  , 0.2  ], 
     [ 0.29999998, 0.29999998, 0.29999998]], 

     [[ 0.40000001, 0.40000001, 0.40000001], 
     [ 0.69999999, 0.69999999, 0.69999999]]], dtype=float32) 
+0

Почему это уменьшается? – AJP

6

Ok, ВНИМАНИЕ У меня нет моих мастеров в numpyology еще, но просто играл, я придумал:

>>> np.average(a,axis=-1).repeat(a.shape[-1]).reshape(a.shape) 
array([[[ 0.2  , 0.2  , 0.2  ], 
     [ 0.29999998, 0.29999998, 0.29999998]], 

     [[ 0.40000001, 0.40000001, 0.40000001], 
     [ 0.69999999, 0.69999999, 0.69999999]]], dtype=float32) 
+0

Мне это нравится, это лучше, чем я придумал. – lukecampbell

+0

Это хорошо работает ... любое преимущество перед ответами Омара или Баго? – AJP

+0

Это одна строка, и она работает для всех форм и размеров массива, пока вы принимаете среднее значение вдоль последней оси. – user545424

5

Рассматривали ли вы с помощью телевидения? Here - это больше информации о вещании, если вы новичок в этой концепции.

Вот пример использования broadcast_arrays, имейте в виду, что b производства здесь broadcast_arrays следует рассматривать как только для чтения, вы должны сделать копию, если вы хотите писать:

>>> b = np.average(a, axis=2)[:, :, np.newaxis] 
>>> b, _ = np.broadcast_arrays(b, a) 
>>> b 
array([[[ 0.2  , 0.2  , 0.2  ], 
     [ 0.29999998, 0.29999998, 0.29999998]], 

     [[ 0.40000001, 0.40000001, 0.40000001], 
     [ 0.69999999, 0.69999999, 0.69999999]]], dtype=float32) 
+0

Это отличная ссылка, спасибо. – AJP

+0

И хороший ответ тоже. – AJP

1

Вот метод, который позволяет избежать изготовления копий:

a = a.T 
a[:] = a.mean(axis=0) 
a = a.T 

Или, если вы не хотите, чтобы перезаписать a:

b = np.empty_like(a) 
b = b.T 
b[:] = a.mean(axis=-1).T 
b = b.T 
+0

И еще один отличный ответ. Как выбрать? Благодаря! :) – AJP

0

Это для произвольной оси:

array является ndimentional массив и axis является ось средней

np.repeat(np.expand_dims(np.mean(array, axis), axis), array.shape[axis], axis)