【问题标题】:Is there a more efficient and elegant way to filter pandas index by date?有没有更有效和优雅的方法来按日期过滤熊猫索引?
【发布时间】:2017-08-23 12:19:49
【问题描述】:

我经常使用 DatetimeIndex.date,尤其是在 groupby 方法中。但是,与 DatetimeIndex.year/month/day 相比,DatetimeIndex.date 速度较慢。据我了解,这是因为 .date 属性与索引上的 lambda 函数一起使用并返回日期时间有序索引,而 index.year/month/day 仅返回整数索引。我做了一个小示例函数,它的性能更好一些,并且会加快我的一些代码(至少对于在 groupby 中查找值),但我觉得必须有更好的方法:

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

pandas/index 是否有我没有找到的类似功能?

【问题讨论】:

    标签: python pandas datetime indexing


    【解决方案1】:

    你甚至可以稍微改进一下:

    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
    

    另一种解决方案 - 使用DataFrame.resample() 方法:

    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
    

    更新:按字符串分组:

    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
    

    【讨论】:

    • df.groupby(df.index.strftime('%Y%m%d')).mean()?
    • @MaxU 完美!非常感谢!
    • @VolkrB,很高兴我能帮上忙 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-17
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    相关资源
    最近更新 更多