2017-04-06 1 views
2

Ich führe eine Operation für jede Spalte eines DataFramedurch, die nach Wochen indiziert ist.. In jeder Spalte zähle ich nämlich das erste Vorkommen, bei dem ein Eintrag nicht gleich dem vorherigen Eintrag ist (ohne den ersten Eintrag), und gebe die Differenz zwischen dem letzten Zeitraum und dem Zeitraum, in dem dies aufgetreten ist, aus.Effizientes Verschieben der Zählung auf einen DataFrame

Das Problem ist, dass dies sehr langsam ist und ich bin mir nicht sicher, wie es zu rationalisieren, möglicherweise unter Verwendung numpy. Hier ist mein Code:

def sh(ser): 
    if ser.drop_duplicates().shape[0]==1: 
     return np.nan 
    s = (ser!=ser.shift())[1:] 
    a=s[s].index[0] 
    b=s.index[-1] 
    c = - (a-b) 
    return c.days/7 + 1 

cols = prices.columns 
timeDiffs = [] 
for col in cols: 
    ser = prices[col] 
    timeDiffs.append(sh(ser)) 
output = pd.Series(timeDiffs) 

Um eine Vorstellung davon zu bekommen, was das bedeutet, wenn `df ist die folgende:

   0  1  2 
index         
2015-11-15  9  15.0 8 
2015-11-22  9  15.0 8 
2015-11-28  3.2 15.0 8 
2015-12-06  3.2 15.0 8 
2015-12-13  4  15.0 8 
2015-12-20  5  15.0 2 

Die output ist:

4 
nan 
1 

Antwort

2

Set der index zu datetime

df.index = pd.to_datetime(df.index) 

df_1 = df.diff(-1).fillna(method='ffill').astype(bool).cumsum().replace(0,np.nan) 
(df_1.idxmax() - df_1.idxmin()).astype('timedelta64[D]')/7 

0 4.0 
1 NaN 
2 1.0 
dtype: float64 
+0

Danke, aber das ergibt [3, nan, 1] anstelle von [4, nan, 1] für das obige Beispiel – splinter

+0

Wie ist die erste Spalte gleich 4? –

+0

, weil so viele Beobachtungen in der Spalte verbleiben, beginnend mit der ersten Periode, in der eine Änderung stattgefunden hat (und sie eingeschlossen hat). Beachten Sie die 'return c.days/7 + 1' im Code. – splinter

1
from pandas import DataFrame 
index = [u'2015-11-15', u'2015-11-22', u'2015-11-28', u'2015-12-06', u'2015-12-13', u'2015-12-20'] 
df = DataFrame({0: [9, 9, 3.2, 3.2, 4, 5], 1: [15, 15, 15, 15, 15, 15], 2: [8, 8, 8, 8, 8, 2]}, index) 
df.apply(lambda x: (x.diff().fillna(0) != 0).astype(int).sum()) 
+0

Danke, aber das gibt [3, nan, 1] anstelle von [4, nan, 1] für das obige Beispiel – splinter

+0

Entschuldigung! Achten Sie nicht auf Ihren Code. Wie viele Zeilen befinden sich in DataFrame? Und wie viel Zeit wird Ihr Code ausführen? – xmduhan

Verwandte Themen