2012-06-01 12 views
6

Tengo una matriz numpy con flotadores.Submuestreo/promediado sobre una matriz numpy

Lo que me gustaría tener (si no existe) es una función que me proporciona una nueva matriz del promedio de cada x puntos en la matriz dada, como submuestreo (y opuesto a la interpolación (?))

E.g. sub_sample (numpy.array ([1, 2, 3, 4, 5, 6]), 2) da [1.5, 3.5, 5.5]

P. ej. Las sobras se pueden eliminar, p. sub_sample (numpy.array ([1, 2, 3, 4, 5]), 2) da [1.5, 3.5]

Gracias de antemano.

Respuesta

17

utilizando rutinas NumPy podría intentar algo así como

import numpy 

x = numpy.array([1, 2, 3, 4, 5, 6]) 

numpy.mean(x.reshape(-1, 2), 1) # Prints array([ 1.5, 3.5, 5.5]) 

y simplemente reemplazar el 2 en la llamada reshape con el número de elementos que desea promediar .

Editar: Esto supone que n se divide en la longitud de x. Deberá incluir algunos controles si va a convertir esto en una función general. Tal vez algo como esto:

def average(arr, n): 
    end = n * int(len(arr)/n) 
    return numpy.mean(arr[:end].reshape(-1, n), 1) 

Esta función en acción:

>>> x = numpy.array([1, 2, 3, 4, 5, 6]) 
>>> average(x, 2) 
array([ 1.5, 3.5, 5.5]) 

>>> x = numpy.array([1, 2, 3, 4, 5, 6, 7]) 
>>> average(x, 2) 
array([ 1.5, 3.5, 5.5]) 
+1

Este funciona bien, excepto cuando el tamaño de la ventana (2 en el ejemplo anterior) no es una multiplicación de la longitud de la matriz, pero puedo asegurarme de que es así. ¡Gracias! –

+1

@MichelKeijzers Solo hay que pensar en eso, ver mi edición. – Chris

+0

gracias ... sí, eso era exactamente lo que también estaba pensando. –

3
def subsample(data, sample_size): 
    samples = list(zip(*[iter(data)]*sample_size)) # use 3 for triplets, etc. 
    return map(lambda x:sum(x)/float(len(x)), samples) 

l = [1, 2, 3, 4, 5, 6] 

print subsample(l, 2) 
print subsample(l, 3) 
print subsample(l, 5) 

Da:

[1.5, 3.5, 5.5] 
[2.0, 5.0] 
[3.0] 
+1

Gracias voy a intentarlo, sin embargo espero que habrá una función numpy porque tienden a ser alrededor de 10 veces más rápido que la mayoría función de Python similar. –

-1

esto también es una solución de una línea que debería funcionar:

downsampled_a = [a[i:n+i].mean() for i in range(0,size(a),n)] 

"a" es el vector con su datos y "n" es su paso de muestreo.

PS: from numpy import *

+0

Devuelve '[1.5, 3.5, 5.0]' - no '[1.5, 3.5]' como lo desee OP. También use 'np.size()' en lugar de importar todo de 'numpy'. –

Cuestiones relacionadas