Terminé resolviéndolo mientras escribía esta pregunta, así que solo publicaré y responderé mi propia pregunta en caso de que alguien más necesite un poco de ayuda.
Supongamos que tenemos un DataFrame
, df
, que contiene estos datos.
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")
Para cada fila, sume los spendings
sobre cada fila que se encuentra dentro de un mes , idealmente utilizando DataFrame.rolling
ya que es una syntax muy clara.
df = df.rolling("M").sum()
Pero esto arroja una excepción.
ValueError: is a non-fixed frequency
versión: pandas==0.19.2
Use el desplazamiento "D"
lugar de "M"
y use específicamente "30D"
durante 30 días o aproximadamente un mes.
df = df.rolling("30D").sum()
Inicialmente, salté intuitivamente a usar "M"
ya que pensé que significaba un mes, pero ahora está claro por qué eso no funciona.
Para abordar por qué no puede usar cosas como “AS” o “Y”, en este caso, “Y” offset no es “un año”, en realidad hace referencia a YearEnd ( http://pandas.pydata.org/pandas-docs /stable/timeseries.html#offset-aliases ), y por lo tanto, la función de desplazamiento no obtiene una ventana fija (por ejemplo, obtiene una ventana de 365 días si su índice cae el 1 de enero y 1 día si es el 31 de diciembre).
La solución propuesta (compensada por 30D) funciona si no necesita meses calendario estrictos. Alternativamente, podría iterar sobre su índice de fecha y dividir con un desplazamiento para obtener un control más preciso sobre su sum.
Si tiene que hacerlo en una línea (separada para facilitar la lectura):
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