熊猫每月滚动操作

Fil*_*rda 14 python pandas

在写出这个问题的时候我最终搞清楚了,所以无论如何我都会发帖并回答我自己的问题以防其他人需要一些帮助.

问题

假设我们有一个DataFrame,df包含该数据.

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")
Run Code Online (Sandbox Code Playgroud)

目标

对于每一行,总结一个月spendings内的每一行,理想情况下使用它是一个非常干净的语法.DataFrame.rolling

我试过了什么

df = df.rolling("M").sum()
Run Code Online (Sandbox Code Playgroud)

但这引发了一个例外

ValueError: <MonthEnd> is a non-fixed frequency
Run Code Online (Sandbox Code Playgroud)

版: pandas==0.19.2

Fil*_*rda 15

使用"D"偏移而不是"M"专门使用"30D"30天或大约一个月.

df = df.rolling("30D").sum()
Run Code Online (Sandbox Code Playgroud)

最初,我直觉地跳到使用,"M"因为我认为它代表了一个月,但现在很清楚为什么这不起作用.

  • 注意:我有一段时间没有看过这个.滚动窗口必须具有固定宽度 - "一个月"不是固定的天数.考虑上面给出的滚动操作如何工作:对于每一行,采取30天内的周围行并求它们.如果它是:对于每一行,采取"一个月"内的周围行并将它们相加,算法将如何确定该月的长度?28天?30天?31天? (5认同)
  • 似乎就是这样.我认为一周不一定总是7天.根据使用的日历系统,有时一年中的最后一周不完全是7天,或者一年中的第一周不是.我不确定这一点,记得不久前在某个地方读过这篇文章. (2认同)

Mik*_*ike 11

为了解决为什么你不能使用像"AS"或"Y"这样的东西,在这种情况下,"Y"偏移不是"一年",它实际上是引用YearEnd(http://pandas.pydata.org/pandas-docs /stable/timeseries.html#offset-aliases),因此滚动功能没有得到一个固定的窗口(例如,如果您的索引在1月1日,则获得365天的窗口,如果在12月31日,则获得1天).

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

如果你必须在一行中(为了便于阅读而分开):

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
Run Code Online (Sandbox Code Playgroud)