средний массив numpy, но сохраняет форму

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

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-массив?

Спасибо.


person AJP    schedule 09.05.2012    source источник
comment
Большой поклонник того, что вы хотите увидеть в вопросе.   -  person lukecampbell    schedule 09.05.2012
comment
В большинстве случаев я могу себе представить, что вещание будет делать это, не требуя трехмерного массива.   -  person tillsten    schedule 10.05.2012


Ответы (4)


Хорошо, ВНИМАНИЕ! У меня еще нет магистра в области нумпиологии, но, просто играя, я придумал:

>>> 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)
person user545424    schedule 09.05.2012
comment
Мне это нравится, это лучше, чем то, что я придумал. - person lukecampbell; 09.05.2012
comment
Это одна линия, и она работает для всех форм и размеров массивов, если вы берете среднее значение по последней оси. - person user545424; 10.05.2012

Вы рассматривали возможность использования трансляции? Здесь есть дополнительная информация о трансляции, если вы новичок в этой концепции.

Вот пример использования 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)
person Bi Rico    schedule 09.05.2012

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

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
person kwgoodman    schedule 09.05.2012
comment
И еще один отличный ответ. Как выбрать ?! Спасибо! :) - person AJP; 10.05.2012

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

array - это размерный массив, а axis - ось для усреднения.

np.repeat( np.expand_dims( np.mean( array, axis ), axis ), array.shape[axis], axis )
person FraDega    schedule 08.10.2013