在 Pandas 中 创建 日期 范围 的 总和

xriantvc  于 2022-11-20  发布在  其他
关注(0)|答案(2)|浏览(147)

我有下面的DataFrame,其中有超过300万行:

  1. VALID_FROM VALID_TO VALUE
  2. 0 2022-01-01 2022-01-02 5
  3. 1 2022-01-01 2022-01-03 2
  4. 2 2022-01-02 2022-01-04 7
  5. 3 2022-01-03 2022-01-06 3

我想创建一个大的date_range,其中包含每个时间戳的值的总和。
对于上面的DataFrame,会得出:

  1. dates val
  2. 0 2022-01-01 7
  3. 1 2022-01-02 14
  4. 2 2022-01-03 12
  5. 3 2022-01-04 10
  6. 4 2022-01-05 3
  7. 5 2022-01-06 3

但是,由于DataFrame有300万多行,我不想对每一行都进行迭代,而且我不知道如何在不进行迭代的情况下进行迭代。有什么建议吗?
目前我的程式码如下所示:

  1. new_df = pd.DataFrame()
  2. for idx, row in dummy_df.iterrows():
  3. dr = pd.date_range(row["VALID_FROM"], end = row["VALID_TO"], freq = "D")
  4. tmp_df = pd.DataFrame({"dates": dr, "val": row["VALUE"]})
  5. new_df = pd.concat(objs=[new_df, tmp_df], ignore_index=True)
  6. new_df.groupby("dates", as_index=False, group_keys=False).sum()

groupby的结果就是我想要的输出。

qvtsj1bj

qvtsj1bj1#

如果性能很重要,则对新行使用Index.repeatDataFrame.loc,创建date列,计数器为GroupBy.cumcount,最后聚合sum

  1. df['VALID_FROM'] = pd.to_datetime(df['VALID_FROM'])
  2. df['VALID_TO'] = pd.to_datetime(df['VALID_TO'])
  3. df1 = df.loc[df.index.repeat(df['VALID_TO'].sub(df['VALID_FROM']).dt.days + 1)]
  4. df1['dates'] = df1['VALID_FROM'] + pd.to_timedelta(df1.groupby(level=0).cumcount(),unit='d')
  5. df1 = df1.groupby('dates', as_index=False)['VALUE'].sum()
  6. print (df1)
  7. dates VALUE
  8. 0 2022-01-01 7
  9. 1 2022-01-02 14
  10. 2 2022-01-03 12
  11. 3 2022-01-04 10
  12. 4 2022-01-05 3
  13. 5 2022-01-06 3
js4nwp54

js4nwp542#

一种选择是构建一个日期列表,从原始 Dataframe 的最小值到最大值,使用带有conditional_join的非相等连接来获得匹配,最后使用groupby和sum:

  1. # pip install pyjanitor
  2. import pandas as pd
  3. import janitor
  4. # build the date pandas object:
  5. dates = df.filter(like='VALID').to_numpy()
  6. dates = pd.date_range(dates.min(), dates.max(), freq='1D')
  7. dates = pd.Series(dates, name='dates')
  8. # compute the inequality join between valid_from and valid_to,
  9. # followed by the aggregation on a groupby:
  10. (df
  11. .conditional_join(
  12. dates,
  13. ('VALID_FROM', 'dates', '<='),
  14. ('VALID_TO','dates', '>='),
  15. # if you have numba installed,
  16. # it can improve performance
  17. use_numba=False,
  18. df_columns='VALUE')
  19. .groupby('dates')
  20. .VALUE
  21. .sum()
  22. )
  23. dates
  24. 2022-01-01 7
  25. 2022-01-02 14
  26. 2022-01-03 12
  27. 2022-01-04 10
  28. 2022-01-05 3
  29. 2022-01-06 3
  30. Name: VALUE, dtype: int64
展开查看全部

相关问题