tutorial - promedio de una matriz python
Agrupando matriz numpy 2D en promedio (4)
Estoy tratando de agrupar una matriz numpy en un tamaño más pequeño tomando el promedio de los elementos. Por ejemplo, tomar el promedio para cada 5x5 subarreglos en un arreglo de 100x100 para crear un arreglo de 20x20. Como tengo una gran necesidad de datos para manipular, ¿es una forma eficiente de hacerlo?
Esto es bastante sencillo, aunque creo que podría ser más rápido:
from __future__ import division
import numpy as np
Norig = 100
Ndown = 20
step = Norig//Ndown
assert step == Norig/Ndown # ensure Ndown is an integer factor of Norig
x = np.arange(Norig*Norig).reshape((Norig,Norig)) #for testing
y = np.empty((Ndown,Ndown)) # for testing
for yr,xr in enumerate(np.arange(0,Norig,step)):
for yc,xc in enumerate(np.arange(0,Norig,step)):
y[yr,yc] = np.mean(x[xr:xr+step,xc:xc+step])
También puede encontrar scipy.signal.decimate interesante. Aplica un filtro de paso bajo más sofisticado que el simple promedio antes de muestrear los datos, aunque tendría que diezmar un eje y luego el otro.
He intentado esto para una matriz más pequeña, así que pruébala con la tuya
import numpy as np
nbig = 100
nsmall = 20
big = np.arange(nbig * nbig).reshape([nbig, nbig]) # 100x100
small = big.reshape([nsmall, nbig//nsmall, nsmall, nbig//nsmall]).mean(3).mean(1)
Un ejemplo con 6x6 -> 3x3:
nbig = 6
nsmall = 3
big = np.arange(36).reshape([6,6])
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],
[24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35]])
small = big.reshape([nsmall, nbig//nsmall, nsmall, nbig//nsmall]).mean(3).mean(1)
array([[ 3.5, 5.5, 7.5],
[ 15.5, 17.5, 19.5],
[ 27.5, 29.5, 31.5]])
Promedio de una matriz 2D sobre subarrays de tamaño NxN:
height, width = data.shape
data = average(split(average(split(data, width // N, axis=1), axis=-1), height // N, axis=1), axis=-1)
Tenga en cuenta que el enfoque de eumiro no funciona para matrices enmascaradas, ya que .mean(3).mean(1)
supone que cada media a lo largo del eje 3 se calculó a partir del mismo número de valores. Si hay elementos enmascarados en su matriz, esta suposición ya no es válida. En ese caso, debe realizar un seguimiento del número de valores utilizados para calcular .mean(3)
y reemplazar .mean(1)
por una media ponderada. Los pesos son el número normalizado de valores utilizados para calcular .mean(3)
.
Aquí hay un ejemplo:
import numpy as np
def gridbox_mean_masked(data, Nbig, Nsmall):
# Reshape data
rshp = data.reshape([Nsmall, Nbig//Nsmall, Nsmall, Nbig//Nsmall])
# Compute mean along axis 3 and remember the number of values each mean
# was computed from
mean3 = rshp.mean(3)
count3 = rshp.count(3)
# Compute weighted mean along axis 1
mean1 = (count3*mean3).sum(1)/count3.sum(1)
return mean1
# Define test data
big = np.ma.array([[1, 1, 2],
[1, 1, 1],
[1, 1, 1]])
big.mask = [[0, 0, 0],
[0, 0, 1],
[0, 0, 0]]
Nbig = 3
Nsmall = 1
# Compute gridbox mean
print gridbox_mean_masked(big, Nbig, Nsmall)