pandas 如何相对于第一次约会重新采样?

lsmepo6l  于 2023-10-14  发布在  其他
关注(0)|答案(4)|浏览(144)

我的系列:

  1. dates = pd.date_range('2018-01-03', '2018-09-13')
  2. s = pd.Series(range(len(dates)), index=dates)

我想重新采样到月份,但从索引的第一天开始,而不是从每月的第一天开始。如果我重新采样为“MS”,第一个日期是2018-01-01,而不是2018-01-03。当然,这是“月份开始”,所以这是预期的。
但是,我如何每月重新采样,而不是从月初开始采样,而是从同一个月的同一天开始采样,因此产生的索引是[“2018-01-03”,“2018-02-03”等](从索引中的第一个日期开始的月份)?
我发现的唯一方法是创建前导日期,做一个负移位,然后使用loffset参数(因为移位和loffset都不考虑数据与索引的对齐)。但我不想这样。

hmtdttj4

hmtdttj41#

获取每月系列

  1. dates = pd.date_range(s.index.min(), s.index.max(), freq='M')

返回到第一次约会之前的MonthEnd并添加天数

  1. dates = dates + pd.offsets.MonthEnd(-1) + pd.offsets.Day(s.index[0].day)

使用reindex

  1. s.reindex(dates)
  2. 2018-01-03 0
  3. 2018-02-03 31
  4. 2018-03-03 59
  5. 2018-04-03 90
  6. 2018-05-03 120
  7. 2018-06-03 151
  8. 2018-07-03 181
  9. 2018-08-03 212
  10. dtype: int64
展开查看全部
qij5mzcb

qij5mzcb2#

我做到这一点的最简单的方法是:
从你最初的例子:

  1. dates = pd.date_range('2018-01-03', '2018-09-13')
  2. s = pd.Series(range(len(dates)), index=dates)
  3. s.resample("30D", origin="start").sum()
  1. 2018-01-03 435
  2. 2018-02-02 1335
  3. 2018-03-04 2235
  4. 2018-04-03 3135
  5. 2018-05-03 4035
  6. 2018-06-02 4935
  7. 2018-07-02 5835
  8. 2018-08-01 6735
  9. 2018-08-31 3451
  10. Freq: 30D, dtype: int64

我知道这个问题很老,我在Pandas 2.0.2上

展开查看全部
vptzau2j

vptzau2j3#

  • (OP的解决方案,最初发布在问题正文中,而不是作为新答案。

我通过这些简单的步骤解决了这个问题,并从一些尝试中调整来解决这个问题(包括answer of piRSquared,还有其他网站和SO的问题):

  1. dates = pd.date_range('2018-01-03', '2018-09-13')
  2. s = pd.Series(range(len(dates)), index=dates)
  3. delta = dates.min() - (dates.min() - offsets.MonthBegin(1))
  4. new_dates = dates - delta
  5. s2 = s.copy()
  6. s2.index = new_dates
  7. resampled = s2.resample('MS', loffset=delta)
  8. r_max = resampled.max()
  9. r_min = resampled.min()
  10. r_mean = resampled.mean()
  11. r_sum = resampled.sum()
  12. print('s\n', s)
  13. print('r_max\n', r_max)
  14. print('r_min\n', r_min)
  15. print('r_mean\n', r_mean)
  16. print('r_sum\n', r_sum)

备选方案

我最终采取了一种不同的方法。我从以下内容开始:

  1. dates = pd.date_range('2015-01-31', '2018-09-13')
  2. start_date: dt.date = dates[0].date()
  3. end_date: dt.date = dates[-1].date()
  4. recurrent_dates = []
  5. next_date = start_date
  6. while next_date <= end_date:
  7. if next_date.day < start_date.day:
  8. try:
  9. next_date = dt.date(
  10. next_date.year, next_date.month, start_date.day)
  11. except ValueError:
  12. next_date = (
  13. next_date + offsets.MonthBegin(1) - offsets.Day(1)
  14. ).date()
  15. recurrent_dates.append(next_date)
  16. next_date += relativedelta(months=1)

要获得从任意日期开始的预期月度周期,请使用上面的重复日期创建DataFrame,然后使用fillna(method="ffill")使用原始DataFrame中的日期重新索引它,然后使用groupby按重复日期分组。
希望这也能帮助到其他人。

展开查看全部
m4pnthwp

m4pnthwp4#

根据你的回答,减少你可以做的计算:

  1. dates = pd.date_range('2018-01-03', '2018-09-13')
  2. s = pd.Series(range(len(dates)), index=dates)
  3. resampled = s.resample('MS', loffset=pd.Timedelta(days=s.index[0].day) - 1)

请注意,我没有复制到S2并分配一个完整的月份索引,因为重新采样已经将初始日期设置为该月的第一天。

相关问题