2017-07-16 4 views
2

Ich habe einen Datenrahmen:Pandas Datenrahmen, caclulate max Spaltenwert relativ zum aktuellen Zeile Spaltenwert

df = pd.DataFrame({ 
    'epoch' : [1, 4, 7, 8, 9, 11, 12, 15, 16, 17], 
    'price' : [1, 2, 3, 3, 1, 4, 2, 3, 4, 4] 
}) 

    epoch price 
0  1  1 
1  4  2 
2  7  3 
3  8  3 
4  9  1 
5  11  4 
6  12  2 
7  15  3 
8  16  4 
9  17  4 

Ich habe eine neue Spalte zu schaffen, die in der folgenden Weise berechnet werden:

Für jeden Reihe

aktuelle Zeile der Epoche finden (sie e_cur sagen)

berechnen e_cur-3 = e_cur - 3 (drei ist eine konstante, hier aber es wird variabel sein)

Preis berechnen Max-Wert, wo Epoche> = e-3_cur und Epoche < = e_cur

Mit anderen Worten: Höchstpreis in Reihen finden, die drei Epochen entfernt sind von den aktuellen Reihe der Epoche.

Zum Beispiel:

Index = 0, = e_cur Epoche = 1, e_cur-3 = 1 -3 = -2, gibt es nur eine (erste) Zeile, deren Epoche ist zwischen -2 und 1, so dass die Preis aus der ersten Zeile ist Maximalpreis

Index = 6, e_cur = Epoche = 12, e_cur-3 = 12 - 3 = 9, es gibt drei Zeilen, deren Epoche zwischen 9 und 12 liegt, aber Reihe mit Index = 5 der Höchstpreis hat = 4.

Hier sind die Ergebnisse für jede Zeile, die ich manuell berechnet:

epoch price max_price_where_epoch_is_between_e_cur-3_and_e_cur 
0  1  1             1 
1  4  2             2 
2  7  3             3 
3  8  3             3 
4  9  1             3 
5  11  4             4 
6  12  2             4 
7  15  3             3 
8  16  4             4 
9  17  4             4 

Wie Sie sehen können, geht Epoche etwas nach dem anderen, aber manchmal gibt es "Löcher".

Wie berechnet man das mit Pandas?

+0

probe 'apply' sollte geben Sie Ihre richtige Antwort – Wen

Antwort

2

Mit Rollfenster:

In [161]: df['between'] = df.epoch.map(df.set_index('epoch') 
    ...:        .reindex(np.arange(df.epoch.min(), df.epoch.max()+1)) 
    ...:        .rolling(3, min_periods=1) 
    ...:        .max()['price']) 
    ...: 

In [162]: df 
Out[162]: 
    epoch price between 
0  1  1  1.0 
1  4  2  2.0 
2  7  3  3.0 
3  8  3  3.0 
4  9  1  3.0 
5  11  4  4.0 
6  12  2  4.0 
7  15  3  3.0 
8  16  4  4.0 
9  17  4  4.0 

Erläuterung:

Helper DF:

In [165]: df.set_index('epoch').reindex(np.arange(df.epoch.min(), df.epoch.max()+1)) 
Out[165]: 
     price 
epoch 
1  1.0 
2  NaN 
3  NaN 
4  2.0 
5  NaN 
6  NaN 
7  3.0 
8  3.0 
9  1.0 
10  NaN 
11  4.0 
12  2.0 
13  NaN 
14  NaN 
15  3.0 
16  4.0 
17  4.0 

In [166]: df.set_index('epoch').reindex(np.arange(df.epoch.min(), df.epoch.max()+1)).rolling(3, min_periods=1).max() 
Out[166]: 
     price 
epoch 
1  1.0 
2  1.0 
3  1.0 
4  2.0 
5  2.0 
6  2.0 
7  3.0 
8  3.0 
9  3.0 
10  3.0 
11  4.0 
12  4.0 
13  4.0 
14  2.0 
15  3.0 
16  4.0 
17  4.0 
+0

Nizza, könnte es effizienter sein. – tarashypka

+0

@tarashypka, danke! Ja, es kann immer effizienter sein ... ;-) – MaxU

+0

Nice Idea, 'reindex' machen das Leben immer einfacher, wenn es an Wert fehlt. – Wen

2

Betrachten Funktion auf epoch Spalte anwenden, wo Sie die erforderlichen Zeilen finden können und berechnen ihre price Maximalwert

>> df['between'] = df['epoch'].apply(lambda e: df.loc[ 
>>    (df['epoch'] >= e - 3) & (df['epoch'] <= e), 'price'].max()) 
>> df 
    epoch price between 
0  1  1  1 
1  4  2  2 
2  7  3  3 
3  8  3  3 
4  9  1  3 
5  11  4  4 
6  12  2  4 
7  15  3  3 
8  16  4  4 
9  17  4  4 
0

Ich habe beide Lösungen versucht, von Tarashypka und MaxU. Die erste Lösung, die ich ausprobiert habe, war Tarashypkas. Ich habe es auf 100k Zeilen getestet. Es dauerte ungefähr eine Minute.

Dann versuchte ich MaxU-Lösung, die in etwa 4 Sekunden abgeschlossen hat.

Ich bevorzuge die Lösung von MaxU wegen der Geschwindigkeit, aber mit der Lösung von Tarashypka habe ich auch gelernt, wie man Lambda-Funktion mit DataFrame verwendet.

Vielen Dank an euch alle.

Mit freundlichen Grüßen und Wünsche.

Verwandte Themen