每月滚动操作

2024-05-13 22:20:27 发布

您现在位置:Python中文网/ 问答频道 /正文

最后我在写这个问题的时候就想出来了,所以我还是发帖子,回答我自己的问题,以防别人需要帮助

问题

假设我们有一个DataFramedf,包含这个数据

import pandas as pd
from io import StringIO

data = StringIO(
"""\
date          spendings  category
2014-03-25    10         A
2014-04-05    20         A
2014-04-15    10         A
2014-04-25    10         B
2014-05-05    10         B
2014-05-15    10         A
2014-05-25    10         A
"""
)

df = pd.read_csv(data,sep="\s+",parse_dates=True,index_col="date")

目标

对于每一行,在距离它一个月之内的每一行上求spendings和,最好使用DataFrame.rolling,因为这是一种非常干净的语法

我试过的

df = df.rolling("M").sum()

但这带来了一个例外

ValueError: <MonthEnd> is a non-fixed frequency

版本:pandas==0.19.2


Tags: 数据fromioimportdataframepandasdfdata
2条回答

为了解释为什么不能使用“AS”或“Y”,在本例中,“Y”偏移量不是“a year”,它实际上是引用YearEnd(http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases),因此滚动函数没有固定的窗口(例如,如果索引在1月1日,则为365天窗口;如果索引在12月31日,则为1天窗口)

如果您不需要严格的日历月,则建议的解决方案(抵消30天)有效。或者,您可以迭代日期索引,并使用偏移量进行切片,以更精确地控制总和

如果必须在一行中完成(为了可读性分开):

df['Sum'] = [
    df.loc[
        edt - pd.tseries.offsets.DateOffset(months=1):edt, 'spendings'
    ].sum() for edt in df.index
]
spendings   category    Sum
date            
2014-03-25  10  A   10
2014-04-05  20  A   30
2014-04-15  10  A   40
2014-04-25  10  B   50
2014-05-05  10  B   50
2014-05-15  10  A   40
2014-05-25  10  A   40

使用"D"偏移量而不是"M",并特别使用"30D"30天或大约一个月

df = df.rolling("30D").sum()

起初,我直觉地开始使用"M",因为我认为它代表一个月,但现在很清楚为什么它不起作用

相关问题 更多 >