2017-12-06 3 views
0

Ich habe einige Zeitreihendaten, die grundsätzlich Informationen über Preisänderung Zeitraum nach Zeitraum enthält. Zum Beispiel, sagen wir mal:Pandas Zeitreihen Daten - Berechnung Produkt über Intervalle unterschiedlicher Länge

df = pd.DataFrame(columns = ['TimeStamp','PercPriceChange']) 
df.loc[:,'TimeStamp']=[1457280,1457281,1457282,1457283,1457284,1457285,1457286] 
df.loc[:,'PercPriceChange']=[0.1,0.2,-0.1,0.1,0.2,0.1,-0.1] 

so dass df sieht aus wie

 TimeStamp PercPriceChange 
0 1457280    0.1 
1 1457281    0.2 
2 1457282    -0.1 
3 1457283    0.1 
4 1457284    0.2 
5 1457285    0.1 
6 1457286    -0.1 

Was will ich erreichen, ist die Gesamtpreisänderung, bevor die eine Zunahme/Abnahme Strähne Enden zu berechnen, und den Wert in der Reihe, wo die Serie begann. Das heißt, was ich will, ist eine Spalte 'TotalPriceChange':

TimeStamp PercPriceChange    TotalPriceChange 
0 1457280    0.1    1.1 * 1.2 - 1 = 0.31 
1 1457281    0.2       0 
2 1457282    -0.1      -0.1 
3 1457283    0.1   1.1 * 1.2 * 1.1 - 1 = 0.452 
4 1457284    0.2       0 
5 1457285    0.1       0 
6 1457286    -0.1      -0.1 

Ich kann die Ausgangspunkte identifizieren mit so etwas wie:

df['turn'] = 0 
df['PriceChange_L1'] = df['PercPriceChange'].shift(periods=1, freq=None, axis=0) 
df.loc[ df['PercPriceChange'] * df['PriceChange_L1'] < 0, 'turn' ] = 1 

TimeStamp PercPriceChange    turn 
0 1457280    0.1   NaN or 1? 
1 1457281    0.2    0 
2 1457282    -0.1    1 
3 1457283    0.1    1 
4 1457284    0.2    0 
5 1457285    0.1    0 
6 1457286    -0.1    1 

Angesichts dieser Spalte "zu erhalten Wende ", ich brauche Hilfe, um mit meiner Aufgabe fortzufahren (oder vielleicht brauchen wir diese" Wende "überhaupt nicht). Ich bin mir ziemlich sicher, dass ich eine verschachtelte for-Schleife schreiben kann, die Zeile für Zeile durch den gesamten DataFrame geht, was ich benötige und die Spalte 'TotalPriceChange' bearbeite, aber da ich dies auf einem ziemlich großen Datensatz machen möchte (denke Minute) oder Stunden-Daten für ein paar Jahre), ich denke, verschachtelte For-Loops werden wirklich langsam sein.

Deshalb wollte ich nur mit Ihnen Experten überprüfen, um zu sehen, ob es eine effiziente Lösung für mein Problem gibt, die mir nicht bekannt ist. Jede Hilfe würde sehr geschätzt werden!

Danke!

+0

ich hel p du mit dem 'df.loc [df ['PercPriceChange'] * df ['PriceChange_L1'] <0, 'turn'] = 1' und dann' df.turn = df.turn.fillna (0) ' –

+0

@ unutbu Ja, ich wollte nur meinen Gedanken veranschaulichen (also sagte ich "sowas"). Ich habe die Codes basierend auf Lucas Kommentar bearbeitet. –

Antwort

0

Die Berechnung, nach der Sie suchen, sieht wie eine groupby/Produktoperation aus. Um die groupby-Operation einzurichten, müssen wir jeder Zeile einen group-Wert zuweisen. Unter die kumulative Summe der turn Spalte ergibt das gewünschte Ergebnis:

df['group'] = df['turn'].cumsum() 
# 0 0 
# 1 0 
# 2 1 
# 3 2 
# 4 2 
# 5 2 
# 6 3 
# Name: group, dtype: int64 

Jetzt können wir die TotalPriceChange Spalte definieren (Modulo ein wenig Aufräumarbeiten) als

df['PercPriceChange_plus_one'] = df['PercPriceChange']+1 
df['TotalPriceChange'] = df.groupby('group')['PercPriceChange_plus_one'].transform('prod') - 1 

import pandas as pd 
df = pd.DataFrame({'PercPriceChange': [0.1, 0.2, -0.1, 0.1, 0.2, 0.1, -0.1], 
        'TimeStamp': [1457280, 1457281, 1457282, 1457283, 1457284, 1457285, 1457286]}) 

df['turn'] = 0 
df['PriceChange_L1'] = df['PercPriceChange'].shift(periods=1, freq=None, axis=0) 
df.loc[ df['PercPriceChange'] * df['PriceChange_L1'] < 0, 'turn' ] = 1 

df['group'] = df['turn'].cumsum() 

df['PercPriceChange_plus_one'] = df['PercPriceChange']+1 
df['TotalPriceChange'] = df.groupby('group')['PercPriceChange_plus_one'].transform('prod') - 1 
mask = (df['group'].diff() != 0) 
df.loc[~mask, 'TotalPriceChange'] = 0 

df = df[['TimeStamp', 'PercPriceChange', 'TotalPriceChange']] 
print(df) 

Ausbeuten

TimeStamp PercPriceChange TotalPriceChange 
0 1457280    0.1    0.320 
1 1457281    0.2    0.000 
2 1457282    -0.1   -0.100 
3 1457283    0.1    0.452 
4 1457284    0.2    0.000 
5 1457285    0.1    0.000 
6 1457286    -0.1   -0.100 
+0

Perfekt! Ich dachte über groupby & product nach, konnte aber nicht herausfinden, wie man die Gruppen-Tags generiert - Ihr .cumsum() hat die Magie gemacht. Vielen Dank! –

Verwandte Themen