Comment regrouper les entrées de DataFrame pandas par date dans une colonne non unique
Un Pandas DataFrame
contient une colonne nommée "date"
qui contient des valeurs datetime
non uniques.
Je peux regrouper les lignes dans ce cadre en utilisant:
data.groupby(data['date'])
Cependant, cela divise les données par les valeurs datetime
. Je voudrais regrouper ces données par année stockée dans la colonne" date". cette page montre comment regrouper par année dans les cas où l'horodatage est utilisé comme index, ce qui n'est pas vrai dans mon cas.
Comment puis-je réaliser ce regroupement?
5 réponses
J'utilise pandas 0.16.2. Cela a de meilleures performances sur mon grand ensemble de données:
data.groupby(data.date.dt.year)
En utilisant l'option dt
et en jouant avec weekofyear
, dayofweek
etc. devient beaucoup plus facile.
La solution D'Ecatmur fonctionnera bien. Ce sera une meilleure performance sur les grands ensembles de données, cependant:
data.groupby(data['date'].map(lambda x: x.year))
Cela devrait fonctionner:
data.groupby(lambda x: data['date'][x].year)
Cela peut être plus facile à expliquer avec un exemple de jeu de données.
Créer Des Exemples De Données
Supposons que nous ayons une seule colonne D'horodatages, date
et une autre colonne sur laquelle nous aimerions effectuer une agrégation, a
.
df = pd.DataFrame({'date':pd.DatetimeIndex(['2012-1-1', '2012-6-1', '2015-1-1', '2015-2-1', '2015-3-1']),
'a':[9,5,1,2,3]}, columns=['date', 'a'])
df
date a
0 2012-01-01 9
1 2012-06-01 5
2 2015-01-01 1
3 2015-02-01 2
4 2015-03-01 3
Il y a plusieurs façons de regrouper par année
- utiliser l'accesseur dt avec
year
propriété - Mettez
date
dans l'index et utiliser la fonction anonyme pour accéder à l'année - Utiliser
resample
méthode - convertir en période pandas
.dt
accesseur avec year
la propriété
Lorsque vous avez une colonne (et non un index) d'horodatages pandas, vous pouvez accéder à beaucoup plus de propriétés et de méthodes supplémentaires avec l'accesseur dt
. Par exemple:
df['date'].dt.year
0 2012
1 2012
2 2015
3 2015
4 2015
Name: date, dtype: int64
Nous pouvons l'utiliser pour former nos groupes et calculer des agrégations sur une colonne particulière:
df.groupby(df['date'].dt.year)['a'].agg(['sum', 'mean', 'max'])
sum mean max
date
2012 14 7 9
2015 6 2 3
Mettez la date dans l'index et utilisez la fonction anonyme pour accéder à l'année
Si vous définissez la colonne date comme index, elle devient un DateTimeIndex avec les mêmes propriétés et méthodes que l'accesseur dt
donne des colonnes normales
df1 = df.set_index('date')
df1.index.year
Int64Index([2012, 2012, 2015, 2015, 2015], dtype='int64', name='date')
Fait intéressant, lorsque vous utilisez la méthode groupby, vous pouvez lui transmettre une fonction. Cette fonction sera implicitement passée à l'index du DataFrame. Donc, nous pouvons obtenir le même résultat d'en haut avec ce qui suit:
df1.groupby(lambda x: x.year)['a'].agg(['sum', 'mean', 'max'])
sum mean max
2012 14 7 9
2015 6 2 3
Utilisez la méthode resample
Si votre colonne date n'est pas dans l'index, vous devez spécifier la colonne avec le paramètre on
. Vous devez également spécifiez l'alias offset sous forme de chaîne.
df.resample('AS', on='date')['a'].agg(['sum', 'mean', 'max'])
sum mean max
date
2012-01-01 14.0 7.0 9.0
2013-01-01 NaN NaN NaN
2014-01-01 NaN NaN NaN
2015-01-01 6.0 2.0 3.0
Convertir en période pandas
Vous pouvez également convertir la colonne date en objet période pandas. Nous devons passer l'alias offset sous forme de chaîne pour déterminer la longueur de la période.
df['date'].dt.to_period('A')
0 2012
1 2012
2 2015
3 2015
4 2015
Name: date, dtype: object
Nous pouvons alors l'utiliser comme un groupe
df.groupby(df['date'].dt.to_period('Y'))['a'].agg(['sum', 'mean', 'max'])
sum mean max
2012 14 7 9
2015 6 2 3
Cela fonctionnera également
data.groupby(data['date'].dt.year)