Après avoir combattu avec NumPy et dateutil pendant des jours, j'ai récemment découvert l'incroyable bibliothèque Pandas. J'ai parcouru la documentation et le code source, mais je ne sais pas comment obtenir date_range()
pour générer des indices aux bons points d'arrêt.
from datetime import date
import pandas as pd
start = date('2012-01-15')
end = date('2012-09-20')
# 'M' is month-end, instead I need same-day-of-month
date_range(start, end, freq='M')
Ce que je veux:
2012-01-15
2012-02-15
2012-03-15
...
2012-09-15
Ce que j'obtiens:
2012-01-31
2012-02-29
2012-03-31
...
2012-08-31
J'ai besoin de morceaux de taille mensuelle qui représentent le nombre variable de jours dans un mois. C'est possible avec dateutil.rrule:
rrule(freq=MONTHLY, dtstart=start, bymonthday=(start.day, -1), bysetpos=1)
Moche et illisible, mais ça marche. Comment puis-je faire cela avec des pandas? J'ai joué avec date_range()
et period_range()
, jusqu'à présent sans succès.
Mon objectif réel est d'utiliser groupby
, crosstab
et/ou resample
pour calculer les valeurs pour chaque période en fonction des sommes/moyens/etc des entrées individuelles au cours de la période. En d'autres termes, je souhaite transformer les données de:
total
2012-01-10 00:01 50
2012-01-15 01:01 55
2012-03-11 00:01 60
2012-04-28 00:01 80
#Hypothetical usage
dataframe.resample('total', how='sum', freq='M', start='2012-01-09', end='2012-04-15')
à
total
2012-01-09 105 # Values summed
2012-02-09 0 # Missing from dataframe
2012-03-09 60
2012-04-09 0 # Data past end date, not counted
Étant donné que Pandas est à l'origine un outil d'analyse financière, je suis pratiquement certain qu'il existe un moyen simple et rapide de le faire. Aide appréciée!
freq='M'
est pour les fréquences de fin de mois (voir ici ). Mais vous pouvez utiliser .shift
pour le décaler de n'importe quel nombre de jours (ou n'importe quelle fréquence d'ailleurs):
pd.date_range(start, end, freq='M').shift(15, freq=pd.datetools.day)
Il n'y a en fait pas de fréquence "jour du mois" (par exemple "DOMXX" comme "DOM09"), mais je ne vois aucune raison de ne pas en ajouter une.
http://github.com/pydata/pandas/issues/2289
Je n'ai pas de solution de contournement simple pour vous pour le moment car resample
nécessite de passer une règle de fréquence connue. Je pense qu'il devrait être augmenté pour pouvoir prendre n'importe quelle plage de dates à utiliser également comme bords de bac arbitraires. Juste une question de temps et de piratage ...
essayer
date_range(start, end, freq=pd.DateOffset(months=1))