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?

54
demandé sur piRSquared 2012-07-09 13:04:33

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.

46
répondu DACW 2016-12-08 19:58:16

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))
67
répondu Wes McKinney 2012-07-09 14:25:27

Cela devrait fonctionner:

data.groupby(lambda x: data['date'][x].year)
12
répondu ecatmur 2012-07-09 12:39:29

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
8
répondu Ted Petrou 2017-11-06 15:34:22

Cela fonctionnera également

data.groupby(data['date'].dt.year)

0
répondu Chetan Kabra 2017-10-08 20:39:27