我的公司使用4-4-5 calendar进行报告。每个月(又称周期)是4周长,除了每3个月是5周长。
熊猫似乎有很好的support for custom calendar periods。然而,我很难找出正确的频率字符串或自定义业务月偏移量来实现4-4-5日历的月份。
例如:
df_index = pd.date_range("2020-03-29", "2021-03-27", freq="D", name="date")
df = pd.DataFrame(
index=df_index, columns=["a"], data=np.random.randint(0, 100, size=len(df_index))
)
df.groupby(pd.Grouper(level=0, freq="4W-SUN")).mean()从周日开始按4周分组,结果如下。前三个月的开始日期是正确的,但我需要每三个月是5周长。第4个月的开始日期应为2020-06-28。
a
date
2020-03-29 16.000000
2020-04-26 50.250000
2020-05-24 39.071429
2020-06-21 52.464286
2020-07-19 41.535714
2020-08-16 46.178571
2020-09-13 51.857143
2020-10-11 44.250000
2020-11-08 47.714286
2020-12-06 56.892857
2021-01-03 55.821429
2021-01-31 53.464286
2021-02-28 53.607143
2021-03-28 45.037037本质上,我想要实现的是这样的东西:
a
date
2020-03-29 20.000000
2020-04-26 50.750000
2020-05-24 49.750000
2020-06-28 49.964286
2020-07-26 52.214286
2020-08-23 47.714286
2020-09-27 46.250000
2020-10-25 53.357143
2020-11-22 52.035714
2020-12-27 39.750000
2021-01-24 43.428571
2021-02-21 49.392857发布于 2021-11-24 05:50:01
Pandas目前只支持年度和季度5253 (也就是4-4-5日历)。
请参见is pandas.tseries.offsets.FY5253和pandas.tseries.offsets.FY5253Quarter
df_index = pd.date_range("2020-03-29", "2021-03-27", freq="D", name="date")
df = pd.DataFrame(index=df_index)
df['a'] = np.random.randint(0, 100, df.shape[0])因此,你确实需要更多的工作来达到周的水平,并维护一个4-4-5日历。您可以使用原生熊猫偏移量对齐到季度,并手动填写4-4-5周模式。
def date_range(start, end, offset_array, name=None):
start = pd.to_datetime(start)
end = pd.to_datetime(end)
index = []
start -= offset_array[0]
while(start<end):
for x in offset_array:
start += x
if start > end:
break
index.append(start)
return pd.Series(index, name=name)此函数接受偏移量列表,而不是常规频率周期,因此它允许在给定数组中的偏移量之后从一个日期移动到另一个日期:
offset_445 = [
pd.tseries.offsets.FY5253Quarter(weekday=6),
4*pd.tseries.offsets.Week(weekday=6),
4*pd.tseries.offsets.Week(weekday=6),
]
df_index_445 = date_range("2020-03-29", "2021-03-27", offset_445, name='date')
Out:
0 2020-05-03
1 2020-05-31
2 2020-06-28
3 2020-08-02
4 2020-08-30
5 2020-09-27
6 2020-11-01
7 2020-11-29
8 2020-12-27
9 2021-01-31
10 2021-02-28
Name: date, dtype: datetime64[ns]一旦创建了索引,它就会返回到聚合逻辑,以获取正确行存储桶中的数据。假设您想要每4周或5周开始的平均值,根据您生成的df_index_445,它可能如下所示:
# calculate the mean on reindex groups
reindex = df_index_445.searchsorted(df.index, side='right') - 1
res = df.groupby(reindex).mean()
# filter valid output
res = res[res.index>=0]
res.index = df_index_445
Out:
a
2020-05-03 47.857143
2020-05-31 53.071429
2020-06-28 49.257143
2020-08-02 40.142857
2020-08-30 47.250000
2020-09-27 52.485714
2020-11-01 48.285714
2020-11-29 56.178571
2020-12-27 51.428571
2021-01-31 50.464286
2021-02-28 53.642857请注意,由于频率不是常规的,pandas会将datetime索引频率设置为None。
https://stackoverflow.com/questions/64882374
复制相似问题