web-dev-qa-db-fra.com

Comment regrouper les entrées de DataFrame pandas par date dans une colonne non unique

Un Pandas DataFrame contient la colonne nommée "date" qui contient des valeurs datetime non uniques. Je peux grouper 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 grouper 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?

58
Boris Gorelik

J'utilise des pandas 0.16.2. Cela a de meilleures performances sur mon grand ensemble de données:

data.groupby(data.date.dt.year)

Utiliser l'option dt et jouer avec weekofyear, dayofweek etc. devient beaucoup plus facile.

54
DACW

la solution d'ecatmur fonctionnera bien. Ce sera une meilleure performance sur de grands ensembles de données, cependant:

data.groupby(data['date'].map(lambda x: x.year))
67
Wes McKinney

Cela devrait fonctionner:

data.groupby(lambda x: data['date'][x].year)
12
ecatmur

Cela pourrait être plus facile à expliquer avec un exemple de jeu de données.

Créer un échantillon de données

Supposons que nous ayons une seule colonne Timestamps, 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

  • Utilisez l'accesseur DT avec la propriété year
  • Mettez date dans l'index et utilisez une fonction anonyme pour accéder à l'année
  • Utiliser la méthode resample
  • Convertir en période de pandas

.dt accesseur avec la propriété year

Lorsque vous avez une colonne (et non un index) d'horodatages de pandas, vous pouvez accéder à de nombreuses autres propriétés et 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 utiliser cela 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

mettre la date dans l'index et utiliser une fonction anonyme pour accéder à l'année

Si vous définissez la colonne de date comme index, elle devient un DateTimeIndex avec les mêmes propriétés et méthodes que l'accesseur dt donne les 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 de date ne figure pas dans l'index, vous devez spécifier la colonne avec le paramètre on. Vous devez également spécifier le alias de décalage en tant que 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 de pandas

Vous pouvez également convertir la colonne de date en objet Période pandas. Nous devons transmettre l'alias de décalage 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 ensuite utiliser cela en tant que 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
10
Ted Petrou