Як згрупувати записи панд 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.