【问题标题】:How to slice very large dataframe by days without walking the entire dataframe each time?如何在不每次遍历整个数据帧的情况下按天切片非常大的数据帧?
【发布时间】:2021-11-07 20:27:12
【问题描述】:

我有两个庞大的日期时间索引和排序数据框,我需要将一个组与另一个组进行比较。

start, end = df.index.min(), df.index.max()

for day in pd.date_range(start.date(), end.date()+a_day, freq='D'):
     current_df = df[df.index.date == day.date()]
     current_df2= df2[df2.index.date == day.date()]

     do_heavy_lift(df, df2)

我认为繁重的工作会花费大部分时间,但按日期切片需要 > 95% 的时间。

经过反思,每次我对数据帧进行切片时,它可能都会遍历整个索引。

有什么方法可以显着改进这种方法吗?索引已排序。我可以:

  1. 告诉它在当天结束后停止搜索?
  2. 还记得前一天结束时它在哪里,并从那里开始第二天吗?

您可以使用以下方法创建示例数据集:

import numpy as np
from datetime import datetime, timedelta

date_today = datetime.now()
days = pd.date_range(date_today, date_today + timedelta(7000), freq='H')

np.random.seed(seed=1111)
data = np.random.randint(1, high=100, size=len(days))
df = pd.DataFrame({'test': days, 'col2': data})
df = df.set_index('test')

np.random.seed(seed=1345)
data = np.random.randint(1, high=100, size=len(days))
df2 = pd.DataFrame({'test': days, 'col2': data})
df2 = df2.set_index('test')
df.sort_index(inplace=True)
df2.sort_index(inplace=True)

CPU时间:用户9分50秒,系统:4.27秒,总计:9分54秒 挂墙时间:10分45秒

【问题讨论】:

    标签: python pandas dataframe python-datetime


    【解决方案1】:

    您可以使用groupby_apply。通过保留日期部分来规范您的日期时间。

    def do_heavy_lift(df):
        # do stuff here
        return ...
    
    out = pd.concat([df1, df2], axis=1) \
            .groupby(lambda x: x.normalize()) \
            .apply(heavy_lift)
    

    【讨论】:

      【解决方案2】:

      每天使用DataFrame.resample 对数据进行分组。然后迭代组,而不是每次显式迭代日期并切片 DataFrame。

      for (date, g1), (date, g2) in zip(df.resample('1D'), df2.resample('1D')):
          do_heavy_lift(g1, g2)
      

      【讨论】:

        猜你喜欢
        • 2022-08-17
        • 2018-11-23
        • 2019-11-25
        • 2019-12-04
        • 2015-04-19
        • 2012-02-01
        • 1970-01-01
        • 2016-12-05
        • 2017-02-25
        相关资源
        最近更新 更多