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

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

我的系列:

dates = pd.date_range('2018-01-03', '2018-09-13')
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#

获取每月系列

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

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

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

使用reindex

s.reindex(dates)

2018-01-03      0
2018-02-03     31
2018-03-03     59
2018-04-03     90
2018-05-03    120
2018-06-03    151
2018-07-03    181
2018-08-03    212
dtype: int64
qij5mzcb

qij5mzcb2#

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

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

s.resample("30D", origin="start").sum()
2018-01-03     435
2018-02-02    1335
2018-03-04    2235
2018-04-03    3135
2018-05-03    4035
2018-06-02    4935
2018-07-02    5835
2018-08-01    6735
2018-08-31    3451
Freq: 30D, dtype: int64

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

vptzau2j

vptzau2j3#

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

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

dates = pd.date_range('2018-01-03', '2018-09-13')
s = pd.Series(range(len(dates)), index=dates)
delta = dates.min() - (dates.min() - offsets.MonthBegin(1))
new_dates = dates - delta
s2 = s.copy()
s2.index = new_dates
resampled = s2.resample('MS', loffset=delta)
r_max = resampled.max()
r_min = resampled.min()
r_mean = resampled.mean()
r_sum = resampled.sum()

print('s\n', s)
print('r_max\n', r_max)
print('r_min\n', r_min)
print('r_mean\n', r_mean)
print('r_sum\n', r_sum)

备选方案

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

dates = pd.date_range('2015-01-31', '2018-09-13')
start_date: dt.date = dates[0].date()
end_date: dt.date = dates[-1].date()
recurrent_dates = []
next_date = start_date
while next_date <= end_date:
    if next_date.day < start_date.day:
        try:
            next_date = dt.date(
                next_date.year, next_date.month, start_date.day)
        except ValueError:
            next_date = (
                    next_date + offsets.MonthBegin(1) - offsets.Day(1)
            ).date()
    recurrent_dates.append(next_date)
    next_date += relativedelta(months=1)

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

m4pnthwp

m4pnthwp4#

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

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

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

相关问题