Pandas通过多次和向前填充来扩大日期范围

klr1opcd  于 2022-09-21  发布在  其他
关注(0)|答案(2)|浏览(182)

我有一个这样的 Dataframe :

  1. DATE MIN_AMOUNT MAX_AMOUNT MIN_DAY MAX_DAY
  2. 01/09/2022 10 20 1 2
  3. 01/09/2022 15 25 4 5
  4. 01/09/2022 30 50 7 10
  5. 05/09/2022 10 20 1 2
  6. 05/09/2022 15 25 4 5
  7. 07/09/2022 15 25 4 5

我想用正向填充将数据框扩展到日期列之间的所有日期范围。所需的输出为:

  1. DATE MIN_AMOUNT MAX_AMOUNT MIN_DAY MAX_DAY
  2. 01/09/2022 10 20 1 2
  3. 01/09/2022 15 25 4 5
  4. 01/09/2022 30 50 7 10
  5. 02/09/2022 10 20 1 2
  6. 02/09/2022 15 25 4 5
  7. 02/09/2022 30 50 7 10
  8. 03/09/2022 10 20 1 2
  9. 03/09/2022 15 25 4 5
  10. 03/09/2022 30 50 7 10
  11. 04/09/2022 10 20 1 2
  12. 04/09/2022 15 25 4 5
  13. 04/09/2022 30 50 7 10
  14. 05/09/2022 10 20 1 2
  15. 05/09/2022 15 25 4 5
  16. 06/09/2022 10 20 1 2
  17. 06/09/2022 15 25 4 5
  18. 07/09/2022 15 25 4 5

你能帮我解决这个问题吗?

clj7thdc

clj7thdc1#

首先将值转换为日期时间,通过DataFrame.set_indexDataFrame.unstack创建帮助器计数器系列g以进行整形,然后将DataFrame.asfreqmethod='ffill'一起使用并通过DataFrame.stack重新整形,通过DataFrame.droplevel移除帮助器级别,将DatetimeIndex转换为列,更改日期时间的格式,最后创建与原始DataFrame相同的数据类型:

  1. df['DATE'] = pd.to_datetime(df['DATE'], dayfirst=True)
  2. g = df.groupby('DATE').cumcount()
  3. df = (df.set_index(['DATE',g])
  4. .unstack()
  5. .asfreq('D', method='ffill')
  6. .stack()
  7. .droplevel(-1)
  8. .reset_index()
  9. .assign(DATE = lambda x: x['DATE'].dt.strftime('%d/%m/%Y'))
  10. .astype(df.dtypes)
  11. )
  12. print (df)
  13. DATE MIN_AMOUNT MAX_AMOUNT MIN_DAY MAX_DAY
  14. 0 2022-01-09 10 20 1 2
  15. 1 2022-01-09 15 25 4 5
  16. 2 2022-01-09 30 50 7 10
  17. 3 2022-02-09 10 20 1 2
  18. 4 2022-02-09 15 25 4 5
  19. 5 2022-02-09 30 50 7 10
  20. 6 2022-03-09 10 20 1 2
  21. 7 2022-03-09 15 25 4 5
  22. 8 2022-03-09 30 50 7 10
  23. 9 2022-04-09 10 20 1 2
  24. 10 2022-04-09 15 25 4 5
  25. 11 2022-04-09 30 50 7 10
  26. 12 2022-05-09 10 20 1 2
  27. 13 2022-05-09 15 25 4 5
  28. 14 2022-06-09 10 20 1 2
  29. 15 2022-06-09 15 25 4 5
  30. 16 2022-07-09 15 25 4 5
展开查看全部
ehxuflar

ehxuflar2#

几个合并应该会对此有所帮助,并且随着数据大小的增加应该仍然是高效的:

获取唯一的日期并从中构建新的 Dataframe :

  1. out = df.DATE.drop_duplicates()
  2. dates = pd.date_range(out.min(), out.max(), freq='D')
  3. dates = pd.DataFrame(dates, columns=['dates'])

合并datesout,然后将结果与原始 Dataframe 合并:

  1. (dates
  2. .merge(
  3. out,
  4. left_on='dates',
  5. right_on='DATE',
  6. how = 'left')
  7. # faster to fill on a Series than a Dataframe
  8. .assign(DATE = lambda df: df.DATE.ffill())
  9. .merge(
  10. df,
  11. on = 'DATE',
  12. how = 'left')
  13. .drop(columns='DATE')
  14. .rename(columns= {'dates':'DATE'})
  15. )
  16. DATE MIN_AMOUNT MAX_AMOUNT MIN_DAY MAX_DAY
  17. 0 2022-09-01 10 20 1 2
  18. 1 2022-09-01 15 25 4 5
  19. 2 2022-09-01 30 50 7 10
  20. 3 2022-09-02 10 20 1 2
  21. 4 2022-09-02 15 25 4 5
  22. 5 2022-09-02 30 50 7 10
  23. 6 2022-09-03 10 20 1 2
  24. 7 2022-09-03 15 25 4 5
  25. 8 2022-09-03 30 50 7 10
  26. 9 2022-09-04 10 20 1 2
  27. 10 2022-09-04 15 25 4 5
  28. 11 2022-09-04 30 50 7 10
  29. 12 2022-09-05 10 20 1 2
  30. 13 2022-09-05 15 25 4 5
  31. 14 2022-09-06 10 20 1 2
  32. 15 2022-09-06 15 25 4 5
  33. 16 2022-09-07 15 25 4 5
展开查看全部

相关问题