2015-08-21 5 views
6

Ich habe Probleme, die nicht-for-Schleife-Version von diesem zu finden. Sprich das ist meine Eingabe:Wie normalisiert man sich durch eine andere Zeile in einem Pandas DataFrame?

In [94]: df 
Out[94]: 
     N experiment color value value2 
0 145000   0  red 0.30 0.363953 
1 14000   1  red 0.31 0.218978 
2 13000   2  red 0.29 0.948070 
3 15000   0 yellow 0.31 0.620201 
4 1200   1 yellow 0.32 0.567513 
5 1400   2 yellow 0.31 0.318197 
6 40000   0 green 0.29 0.947226 
7 3000   1 green 0.31 0.084243 
8 7000   2 green 0.32 0.961020 

[9 rows x 5 columns] 

Experiment 0 ist meine Kontrolle. Ich habe dieses Experiment für verschiedene Farben durchgeführt. Ich möchte alle Zeilen durch die passende Farb Experiment normalisieren 0.

In [104]: df 
Out[104]: 
     N experiment color value value2 scaled_value scaled_value2 
0 145000   0  red 0.30 0.363953  1.000000  1.000000 
1 14000   1  red 0.31 0.218978  1.033333  0.590786 
2 13000   2  red 0.29 0.948070  0.966667  2.604732 
3 15000   0 yellow 0.31 0.620201  1.000000  1.000000 
4 1200   1 yellow 0.32 0.567513  1.032258  0.914220 
5 1400   2 yellow 0.31 0.318197  1.000000  0.512737 
6 40000   0 green 0.29 0.947226  1.000000  1.000000 
7 3000   1 green 0.31 0.084243  1.068966  0.088680 
8 7000   2 green 0.32 0.961020  1.103448  1.014541 

[9 rows x 7 columns] 

Es scheint, ich würde das Experiment Null-Parameter auf ihre eigene Spalte, genaue wollen einfach Teilung zu ermöglichen, aber ich kann nicht die Stapelung/Schwenk erhalten/concat'ing um richtig zu arbeiten. Ich tat dies mit for-Schleifen mit .at und Zuweisung von Werten, aber es fühlte sich so falsch an.

Die nächsten Schritte werden mehrere Spalten normalisieren würde und upplower und unteren Fehlergrenzen berechnet aus (N, value) zu schaffen, (N, Wert2), (N, other_values) usw.

+0

Blick in 'sklearn' des' MinMaxScaler'; Ich würde mir vorstellen, dass sie die Vektoroperationen optimiert haben. Auch ziemlich sicher, dass Sie es 'pandas' Daten füttern können http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html – Ryan

+0

@Ryan, ist das nicht für die Skalierung der Werte in einer einzigen Spalte/Array? Wenn ich normalize sage, meine ich nicht die Vektorbereiche (0,1), sondern dass jeder durch einen äußeren Wert geteilt wird. – physicsmichael

Antwort

4

Eine Möglichkeit wäre die Verwendung zur transform (hier mit idxmin, obwohl es viele Alternativen gibt) die Indizes der Zeilen erhalten wir als Nenner nutzen wollen:

>>> ii = df.groupby("color")["experiment"].transform("idxmin") 
>>> cols = ["value", "value2"] 
>>> new_cols = (df.loc[:,cols] /df.loc[ii, cols].values) 
>>> df.join(new_cols.rename(columns=lambda x: "scaled_" + x)) 
     N experiment color value value2 scaled_value scaled_value2 
0 145000   0  red 0.30 0.363953  1.000000  1.000000 
1 14000   1  red 0.31 0.218978  1.033333  0.601666 
2 13000   2  red 0.29 0.948070  0.966667  2.604924 
3 15000   0 yellow 0.31 0.620201  1.000000  1.000000 
4 1200   1 yellow 0.32 0.567513  1.032258  0.915047 
5 1400   2 yellow 0.31 0.318197  1.000000  0.513055 
6 40000   0 green 0.29 0.947226  1.000000  1.000000 
7 3000   1 green 0.31 0.084243  1.068966  0.088937 
8 7000   2 green 0.32 0.961020  1.103448  1.014563 

Schritt für Schritt, zuerst finden wir die Nenner Indizes:

>>> ii = df.groupby("color")["experiment"].transform("idxmin") 
>>> ii 
0 0 
1 0 
2 0 
3 3 
4 3 
5 3 
6 6 
7 6 
8 6 
dtype: int64 

Dann können wir dies Index in den Rahmen verwenden:

>>> df.loc[ii, cols] 
    value value2 
0 0.30 0.363953 
0 0.30 0.363953 
0 0.30 0.363953 
3 0.31 0.620201 
3 0.31 0.620201 
3 0.31 0.620201 
6 0.29 0.947226 
6 0.29 0.947226 
6 0.29 0.947226 

Da wir die Ausrichtung selbst sind Handhabung, müssen wir .values rufen nach unten sonst Pandas auf die zugrunde liegenden array-- sinken versuchen Sie uns zu überlisten und richten Sie die Dinge anhand der Indizes korrekt aus.

Dann teilen wir:

>>> (df.loc[:,cols] /df.loc[ii, cols].values) 
     value value2 
0 1.000000 1.000000 
1 1.033333 0.601666 
2 0.966667 2.604924 
3 1.000000 1.000000 
4 1.032258 0.915047 
5 1.000000 0.513055 
6 1.000000 1.000000 
7 1.068966 0.088937 
8 1.103448 1.014563 

und sie schließlich verbinden, die neuen Spalten Umbenennung:

>>> df.join(new_cols.rename(columns=lambda x: "scaled_" + x)) 
     N experiment color value value2 scaled_value scaled_value2 
0 145000   0  red 0.30 0.363953  1.000000  1.000000 
1 14000   1  red 0.31 0.218978  1.033333  0.601666 
2 13000   2  red 0.29 0.948070  0.966667  2.604924 
3 15000   0 yellow 0.31 0.620201  1.000000  1.000000 
4 1200   1 yellow 0.32 0.567513  1.032258  0.915047 
5 1400   2 yellow 0.31 0.318197  1.000000  0.513055 
6 40000   0 green 0.29 0.947226  1.000000  1.000000 
7 3000   1 green 0.31 0.084243  1.068966  0.088937 
8 7000   2 green 0.32 0.961020  1.103448  1.014563 
Verwandte Themen