我有几天1分钟数据的时间序列,并希望在一天中的所有日期对其进行平均。
这很慢:
from datetime import datetime
from pandas import date_range, Series
time_ind = date_range(datetime(2013, 1, 1), datetime(2013, 1, 10), freq='1min')
all_data = Series(randn(len(time_ind)), time_ind)
time_mean = all_data.groupby(lambda x: x.time()).mean()
差不多花了一分钟才能跑完!
类似于:
time_mean = all_data.groupby(lambda x: x.minute).mean()
只需要几分之一秒。
是否有更快的方式按时间分组?
知道为什么这么慢?
答案 0 :(得分:2)
版本0.11.0中,version 0.11中引入的“lambda-version”和time属性似乎都很慢:
In [4]: %timeit all_data.groupby(all_data.index.time).mean()
1 loops, best of 3: 11.8 s per loop
In [5]: %timeit all_data.groupby(lambda x: x.time()).mean()
Exception RuntimeError: 'maximum recursion depth exceeded while calling a Python object' in <type 'exceptions.RuntimeError'> ignored
Exception RuntimeError: 'maximum recursion depth exceeded while calling a Python object' in <type 'exceptions.RuntimeError'> ignored
Exception RuntimeError: 'maximum recursion depth exceeded while calling a Python object' in <type 'exceptions.RuntimeError'> ignored
1 loops, best of 3: 11.8 s per loop
使用当前的master,两种方法都要快得多:
In [1]: pd.version.version
Out[1]: '0.11.1.dev-06cd915'
In [5]: %timeit all_data.groupby(lambda x: x.time()).mean()
1 loops, best of 3: 215 ms per loop
In [6]: %timeit all_data.groupby(all_data.index.time).mean()
10 loops, best of 3: 113 ms per loop
'0.11.1.dev-06cd915'
所以你可以更新到主人或者等待本月应该发布的0.11.1。
答案 1 :(得分:2)
分组小时/分钟/ ..属性而不是.time
更快。这是杰夫的基线:
In [11]: %timeit all_data.groupby(all_data.index.time).mean()
1 loops, best of 3: 202 ms per loop
并且没有时间它会更快(属性越少,越快):
In [12]: %timeit all_data.groupby(all_data.index.hour).mean()
100 loops, best of 3: 5.53 ms per loop
In [13]: %timeit all_data.groupby([all_data.index.hour, all_data.index.minute, all_data.index.second, all_data.index.microsecond]).mean()
10 loops, best of 3: 20.8 ms per loop
注意:时间对象不接受纳秒(但具有DatetimeIndex的分辨率)。
我们应该将索引转换为具有时间对象以使此比较公平:
In [21]: res = all_data.groupby([all_data.index.hour, all_data.index.minute, all_data.index.second, all_data.index.microsecond]).mean()
In [22]: %timeit res.index.map(lambda t: datetime.time(*t))
1000 loops, best of 3: 1.39 ms per loop
In [23]: res.index = res.index.map(lambda t: datetime.time(*t))
因此,对于最大分辨率,它的速度提高了大约10倍,并且您可以轻松地使其更粗糙(和更快),例如只需要时间和分钟..