2012-06-01 10 views
6

Ich habe ein numpy Array mit Floats.Subsampling/Mittelung über ein numpy Array

Was ich gerne hätte (wenn es nicht bereits existiert), ist eine Funktion, die mir ein neues Array des Durchschnitts jedes x Punktes im gegebenen Array gibt, wie Unterabtastung (und Gegenteil von Interpolation (?)).

z. sub_sample (numpy.array ([1, 2, 3, 4, 5, 6]), 2) ergibt [1,5, 3,5, 5,5]

z. Reste können entfernt werden, z.B. sub_sample (numpy.array ([1, 2, 3, 4, 5]), 2) ergibt [1.5, 3.5]

Vielen Dank im Voraus.

Antwort

17

Mit NumPy Routinen Sie so etwas wie

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

könnten versuchen, und ersetzen Sie einfach den 2 im reshape Anruf mit der Anzahl der Artikel, die Sie über mitteln wollen .

Bearbeiten: Dies setzt voraus, dass n in die Länge von x unterteilt. Sie müssen einige Überprüfungen einbeziehen, wenn Sie dies zu einer allgemeinen Funktion machen wollen. Vielleicht so etwas wie diese:

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

Diese Funktion in Aktion:

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

Dieser funktioniert gut, außer wenn die Fenstergröße (2 im obigen Beispiel) keine Multiplikation der Länge des Arrays ist, aber ich kann sicherstellen, dass dies der Fall ist. Vielen Dank! –

+1

@MichelKeijzers Nur eine Hand darüber nachdenken, siehe meine Bearbeitung. – Chris

+0

danke ... ja das war genau das worüber ich auch nachgedacht habe. –

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) 

Gibt:

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

Danke ich werde es versuchen, aber ich hoffe, es wird eine numpy Funktion sein, weil sie dazu neigen, etwa 10-mal schneller als die meisten ähnlichen Python-Funktion zu sein. –

-1

dies ist auch eine eine Zeile Lösung, die funktionieren soll:

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

"a" ist der Vektor mit Ihrem Daten und "n" ist Ihr Stichprobenschritt.

PS: from numpy import *

+0

Es gibt '[1.5, 3.5, 5.0]' - nicht '[1.5, 3.5]' zurück, wie von OP gewünscht. Verwenden Sie auch 'np.size()' anstatt alle von 'numpy' zu importieren. –