2016-05-20 7 views
2

Ich habe eine listX enthält die Daten von verschiedenen Benutzern N durchgeführt, so dass die Nummer des Benutzers ist i=0,1,....,N-1. Jeder Eintrag Xi hat eine andere Länge. Ich möchte den Wert jedes Benutzers Xi über den globalen Datensatz X normalisieren.Python: Wie man einen Normalisierungsalgorithmus verbessert?

Das ist, was ich tue. Zunächst einmal erstelle ich eine 1D Liste, die alle Daten enthalten, so:

tmp = list() 
for i in range(0,len(X)): 
    tmp.extend(X[i]) 

dann wandle ich es in ein Array und ich entfernen Ausreißer und NaN.

A = np.array(tmp) 
A = A[~np.isnan(A)] #remove NaN 
tr = np.percentile(A,95) 
A = A[A < tr] #remove outliers 

und dann schaffe ich das Histogramm des Datensatzes

p, x = np.histogram(A, bins=10) # bin it into n = N/10 bins 

schließlich ich den Wert jeder Benutzer über das Histogramm normalisieren ich erstellt, so:

Xn = list() 
for i in range(0,len(X)): 
    tmp = np.array(X[i]) 
    tmp = tmp[tmp < tr] 
    tmp = np.histogram(tmp, x) 
    Xn.append(append(tmp[0]/sum(tmp[0])) 

Meine Datensatz ist sehr groß und dieser Prozess könnte eine Weile dauern. Ich frage mich, ob es einen besseren Weg gibt, das oder ein Paket zu machen.

Antwort

0

Für den ersten Teil, wenn jedes Element X[i] von X eine Liste ist, können Sie in der Lage sein sum, zu verwenden und dann direkt in ein Array umwandeln, oder verwenden Sie concatenate:

# Example X 
X = [list(range(i)) for i in range(3, 19)] + [[2., np.NaN]] 
# Build array with sum 
A = np.array(sum(X, [])) 
# Build array with concatenate 
A = np.concatenate(X) 

Letztere mehr ist lesbar.

Für den zweiten Teil würde ich Indizes des Benutzers speichern, zu dem jeder Datenpunkt gehört.

idx = np.concatenate([np.full(len(x), i, int) for i,x in enumerate(X)]) 
tr = np.nanpercentile(A,95) 
ok = A < tr # this excludes outliers, +Inf and NaN 
idx = idx[ok] 
A = A[ok] 

Schließlich können Sie x aus dem Bereich von A berechnen, dann digitize auf A verwenden und die Behälter jedes Element erhalten. Dann identifiziert jedes Paar (idx,bin-1) das Datum eines gegebenen Benutzers, der zu einer gegebenen Ablage gehört. Sie können dann alle diese Beiträge mit der at-Methode der ufuncadd (see documentation) summieren. Schließlich dividieren Sie sich durch die Summe über Bins, um zu normalisieren.

x = np.linspace(A.min(), A.max(), 10+1) 
bin = np.digitize(A, x) 
Xn = np.zeros((len(X), len(x))) 
np.add.at(Xn, (idx,bin-1), 1) 
Xn /= Xn.sum(axis=1)[:,np.newaxis] 
Verwandte Themen