2012-06-01 15 views
6

Ho una matrice numpy con float.Sottocampionamento/calcolo della media su un array numpy

Quello che vorrei avere (se non è già esistente) è una funzione che mi dà una nuova matrice della media di ogni punto x nell'array dato, come sub campionamento (e opposto di interpolazione (?)).

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

E.g. Gli avanzi possono essere rimossi, ad es. sub_sample (numpy.array ([1, 2, 3, 4, 5]), 2) dà [1.5, 3.5]

Grazie in anticipo.

risposta

17

Uso routine NumPy si potrebbe provare qualcosa di simile

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

e basta sostituire il 2 nella chiamata reshape con il numero di elementi che si desidera media nel .

Edit: Ciò presuppone che si divide in n la lunghezza del x. Dovrai includere alcuni controlli se hai intenzione di trasformarlo in una funzione generale. Forse qualcosa di simile:

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

Questa funzione in azione:

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

Questo funziona correttamente, tranne quando la dimensione della finestra (2 nell'esempio sopra) non è una moltiplicazione della lunghezza dell'array ma posso assicurarmi che sia così. Grazie! –

+1

@MichelKeijzers Basta pensare a quello, vedere la mia modifica. – Chris

+0

grazie ... sì, quello era esattamente ciò a cui stavo 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) 

Dà:

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

Grazie Cercherò, tuttavia spero che ci sarà una funzione NumPy perché tendono ad essere circa 10 volte più veloce come la maggior parte funzione Python simile. –

-1

questa è anche una soluzione di una linea che dovrebbe funzionare:

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

"a" è il vettore con il tuo i dati e "n" sono il tuo passo di campionamento.

PS: from numpy import *

+0

Restituisce '[1.5, 3.5, 5.0]' - non '[1.5, 3.5]' come desiderato da OP. Usa anche 'np.size()' invece di importare tutto da 'numpy'. –