2012-05-09 20 views
8

Mam 3-osiową tablicę Numpy, której elementy są trójwymiarowe. Chciałbym je uśrednić i zwrócić ten sam kształt tablicy. Normalna średnia funkcja usuwa 3 wymiarach i zastąpić ją ze średnią (zgodnie z oczekiwaniami):średnia tablica numpy, ale zachowuje kształt

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

Wynik wymagane:

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

można to zrobić elegancko, czy mam tylko do iteracji nad tablicą w Pythonie (która będzie dużo wolniejsza w porównaniu do potężnej funkcji Numpy).

Czy można ustawić argument Dtype dla funkcji np.mean na tablicę 1D?

Dzięki.

+2

wielkim fanem, co chcesz zobaczyć w pytaniu. – lukecampbell

+0

W większości przypadków mogę sobie wyobrazić, że transmisja będzie odbywać się bez konieczności stosowania tablicy 3d. – tillsten

Odpowiedz

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

Dlaczego jest to odrzucane? – AJP

6

Ok, UWAGA nie mam moich mistrzów w numpyology jeszcze, ale po prostu grając, wymyśliłem:

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

Podoba mi się, to lepsze niż to, co wymyśliłem. – lukecampbell

+0

To działa dobrze .... jakąkolwiek przewagę nad odpowiedziami Lobstera lub Bago? – AJP

+0

To jedna linia i działa dla wszystkich kształtów i rozmiarów matrycy, o ile przyjmujesz średnią wzdłuż ostatniej osi. – user545424

5

Czy można uznać za pomocą transmisji? Here to więcej informacji o nadawaniu, jeśli nie znasz tej koncepcji.

Oto przykład przy użyciu broadcast_arrays pamiętać, że b produkowane tu broadcast_arrays należy traktować jako tylko do odczytu, należy wykonać kopię, jeśli chcesz napisać do niego:

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

To wspaniałe połączenie, dzięki. – AJP

+0

I też dobra odpowiedź. – AJP

1

Oto metoda, która pozwala uniknąć dokonywania kopii:

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

Lub jeśli nie chcesz nadpisać a:

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

I kolejna wspaniała odpowiedź. Jak wybrać ?! Dzięki! :) – AJP

0

To jest dla dowolnej osi:

array jest ndimentional tablica i axis jest osią średniego

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