2012-05-09 20 views
8

Tengo una matriz Numpy de 3 ejes cuyos elementos son tridimensionales. Me gustaría promediarlos y devolver la misma forma de la matriz. La función normal promedio elimina las 3 dimensiones y sustituirla por la media (como se esperaba):matriz numpy promedio pero conserva la forma

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

resultado requerido:

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

Se puede hacer esto con elegancia o hacerlo sólo tengo que repetir sobre la matriz en Python (que será mucho más lenta en comparación con una poderosa función Numpy).

¿Se puede establecer el argumento Dtype, para la función np.mean, en una matriz 1D quizás?

Gracias.

+2

gran fan de lo que quiere ver en la cuestión. – lukecampbell

+0

En la mayoría de los casos que puedo imaginar, la radiodifusión lo hará sin requerir una matriz 3D. – tillsten

Respuesta

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

¿Por qué esto se degrada? – AJP

6

Ok, PRECAUCIÓN no tengo mis maestros en numpyology todavía, pero simplemente jugando, se me ocurrió:

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

Me gusta, eso es mejor de lo que se me ocurrió. – lukecampbell

+0

Esto funciona bien .... ¿Alguna ventaja sobre las respuestas de Lobster o Bago? – AJP

+0

Es una línea y funciona para todas las formas y tamaños de matriz siempre que tome el promedio a lo largo del último eje. – user545424

5

¿Ha considerado el uso de radiodifusión? Here es más información sobre la transmisión si eres nuevo en el concepto.

Aquí hay un ejemplo usando broadcast_arrays, tenga en cuenta que la b producido aquí por broadcast_arrays deben ser tratados como de sólo lectura, debe hacer una copia si desea escribir en él:

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

Ese es un enlace brillante, gracias. – AJP

+0

Y una buena respuesta también. – AJP

1

Aquí es un método que evita la realización de copias:

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

O si no desea sobrescribir a:

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

Y otra gran respuesta. ¿Cómo elijo? ¡Gracias! :) – AJP

0

Esto es para un eje arbitrario:

array es la matriz ndimentional y axis es el eje de la media

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