首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Pandas中定义4-4-5周

如何在Pandas中定义4-4-5周
EN

Stack Overflow用户
提问于 2020-11-18 03:51:16
回答 1查看 159关注 0票数 0

我的公司使用4-4-5 calendar进行报告。每个月(又称周期)是4周长,除了每3个月是5周长。

熊猫似乎有很好的support for custom calendar periods。然而,我很难找出正确的频率字符串或自定义业务月偏移量来实现4-4-5日历的月份。

例如:

代码语言:javascript
复制
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。

代码语言:javascript
复制
                    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

本质上,我想要实现的是这样的东西:

代码语言:javascript
复制
                    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
EN

回答 1

Stack Overflow用户

发布于 2021-11-24 05:50:01

Pandas目前只支持年度和季度5253 (也就是4-4-5日历)。

请参见is pandas.tseries.offsets.FY5253pandas.tseries.offsets.FY5253Quarter

代码语言:javascript
复制
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周模式。

代码语言:javascript
复制
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)

此函数接受偏移量列表,而不是常规频率周期,因此它允许在给定数组中的偏移量之后从一个日期移动到另一个日期:

代码语言:javascript
复制
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,它可能如下所示:

代码语言:javascript
复制
# 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。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64882374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档