2017-03-29 1 views
1

Ich verwende oft DatetimeIndex.date, besonders in groupby Methoden. DatetimeIndex.date ist jedoch langsam im Vergleich zu DatetimeIndex.year/month/day. Ich verstehe das, weil das .date-Attribut mit einer Lambda-Funktion über dem Index arbeitet und einen datetime-geordneten Index zurückgibt, während index.year/month/day nur ganzzahlige Indizes zurückgibt. Ich habe eine kleines Beispiel Funktion gemacht, die ein bisschen besser abschneidet und würden einige meinen Code beschleunigen (die Werte in einem groupby zumindest für die Suche), aber ich glaube, dass es ein besserer Weg geben:Gibt es eine effizientere und elegantere Methode, den Pandas-Index nach Datum zu filtern?

In [217]: index = pd.date_range('2011-01-01', periods=100000, freq='h') 

In [218]: data = np.random.rand(len(index)) 

In [219]: df = pd.DataFrame({'data':data},index) 

In [220]: def func(df): 
...:  groupby = df.groupby([df.index.year, df.index.month, df.index.day]).mean() 
...:  index = pd.date_range(df.index[0], periods = len(groupby), freq='D') 
...:  groupby.index = index 
...:  return groupby 
...: 

In [221]: df.groupby(df.index.date).mean().equals(func(df)) 
Out[221]: True 

In [222]: df.groupby(df.index.date).mean().index.equals(func(df).index) 
Out[222]: True 

In [223]: %timeit df.groupby(df.index.date).mean() 
1 loop, best of 3: 1.32 s per loop 

In [224]: %timeit func(df) 
10 loops, best of 3: 89.2 ms per loop 

Hat der Pandas/Index eine ähnliche Funktionalität, die ich nicht finde?

Antwort

2

Sie können es sogar ein wenig verbessern:

In [69]: %timeit func(df) 
10 loops, best of 3: 84.3 ms per loop 

In [70]: %timeit df.groupby(pd.TimeGrouper('1D')).mean() 
100 loops, best of 3: 6 ms per loop 

In [84]: %timeit df.groupby(pd.Grouper(level=0, freq='1D')).mean() 
100 loops, best of 3: 6.48 ms per loop 

In [71]: (func(df) == df.groupby(pd.TimeGrouper('1D')).mean()).all() 
Out[71]: 
data True 
dtype: bool 

eine andere Lösung - mit DataFrame.resample() Methode:

In [73]: (df.resample('1D').mean() == func(df)).all() 
Out[73]: 
data True 
dtype: bool 

In [74]: %timeit df.resample('1D').mean() 
100 loops, best of 3: 6.63 ms per loop 

UPDATE: Gruppierung durch die Zeichenfolge:

In [75]: %timeit df.groupby(df.index.strftime('%Y%m%d')).mean() 
1 loop, best of 3: 2.6 s per loop 

In [76]: %timeit df.groupby(df.index.date).mean() 
1 loop, best of 3: 1.07 s per loop 
+1

' df.groupby (df.index.strftime ('% Y% m% d')). mittel() '? – piRSquared

+1

@piRSquared, hinzugefügt entsprechendes Timing ... – MaxU

+0

@MaxU Perfekt! Danke vielmals! – VolkrB

Verwandte Themen