Як згрупувати записи панд DataFrame за датою в не унікальний стовпець


82

Панда DataFrameмістить стовпець із іменем, "date"який містить не унікальні datetimeзначення. Я можу згрупувати рядки в цьому кадрі за допомогою:

data.groupby(data['date'])

Однак це розділяє дані на datetimeзначення. Я хотів би згрупувати ці дані за роком, що зберігається у стовпці "дата". Ця сторінка показує, як групувати за роками у випадках, коли позначка часу використовується як індекс, що в моєму випадку не відповідає дійсності.

Як досягти цього групування?


Для тих, хто приїжджає сюди в 2017+, існує кілька нових способів групуватися за певний час. Дивіться цю відповідь нижче
Тед Петру,

Відповіді:


91

Я використовую панди 0.16.2. Це покращило продуктивність мого великого набору даних:

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

Використовуючи dtопцію і грати з weekofyear, і dayofweekтак далі стає набагато простіше.


Погодьтесь, це, здається, пандаїчний спосіб доступу до атрибутів дати для серії.
dancow

74

Розчин ecatmur буде добре працювати. Це буде кращою продуктивністю на великих наборах даних, однак:

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

9
Чому карту замість застосовувати?
Gus

1
Afaik, mapяк правило, має деякі хороші ефективні якості при застосуванні довільних функцій порівняно з просто використанням apply.
Coolio2654,

25

Це може бути простіше пояснити на прикладі набору даних.

Створення зразкових даних

Давайте припустимо , що у нас є один стовпець позначки часу, dateі ще один стовпець , ми хотіли б виконати агрегацію на, 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

Існує кілька способів групування за роками

  • Використовуйте аксесуар dt із yearвластивістю
  • Вставте dateіндекс та використовуйте анонімну функцію для доступу до року
  • Використовуйте resampleметод
  • Перетворити на панди Період

.dtаксесуар з yearмайном

Коли у вас є стовпець (а не індекс) панд Timestamps, ви можете отримати доступ до багатьох додаткових властивостей та методів за допомогою dtзасобу доступу. Наприклад:

df['date'].dt.year

0    2012
1    2012
2    2015
3    2015
4    2015
Name: date, dtype: int64

Ми можемо використовувати це для формування наших груп та обчислення деяких агрегатів у певному стовпці:

df.groupby(df['date'].dt.year)['a'].agg(['sum', 'mean', 'max'])

      sum  mean  max
date                
2012   14     7    9
2015    6     2    3

помістіть дату в індекс та використовуйте анонімну функцію для доступу до року

Якщо стовпець дати встановити як індекс, він стає DateTimeIndex з тими ж властивостями та методами, що і доступ, який dtнадає звичайні стовпці

df1 = df.set_index('date')
df1.index.year

Int64Index([2012, 2012, 2015, 2015, 2015], dtype='int64', name='date')

Цікаво, що, використовуючи метод groupby, ви можете передати йому функцію. Ця функція буде неявно передана індексу DataFrame. Отже, ми можемо отримати той самий результат згори із наступним:

df1.groupby(lambda x: x.year)['a'].agg(['sum', 'mean', 'max'])

      sum  mean  max
2012   14     7    9
2015    6     2    3

Використовуйте resampleметод

Якщо стовпця дати немає в індексі, необхідно вказати стовпець із onпараметром. Вам також потрібно вказати псевдонім зміщення як рядок.

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

Перетворити на панди Період

Ви також можете перетворити стовпець дати в об'єкт Pandas Period. Ми повинні передати псевдонім зміщення як рядок, щоб визначити довжину Періоду.

df['date'].dt.to_period('A')

0   2012
1   2012
2   2015
3   2015
4   2015
Name: date, dtype: object

Потім ми можемо використовувати це як групу

df.groupby(df['date'].dt.to_period('Y'))['a'].agg(['sum', 'mean', 'max'])


      sum  mean  max
2012   14     7    9
2015    6     2    3

В останньому методі, де ви використовуєте to_period('A'), для чого це ("А")?
shiv_90

2
@ Shiv_90 'A'- це offset-псевдонім часових рядків
ptim

Який метод ви б порадили, якщо вам також потрібно зберегти окремий стовпець "дата"? Наприклад, якщо я запускаю простий .dt.yearметод і зберігаю його в новому фреймі даних, дати зберігаються як індекси, і це стає проблематичним, якщо кажуть, що мені потрібно побудувати графік даних, оскільки стовпець "дати" насправді не є, а лише три надано.agg()
shiv_90


0

це також спрацює

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


Має працювати, але при виконанні він видає розташування об’єкта в пам’яті, але не дає реального виводу. <pandas.core.groupby.DataFrameGroupBy object at 0x10d7f6438>це те, що я отримую при виконанні.
shiv_90
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.