Пропустить до содержимого

Как использовать 'group by' в Python?

[

pandas GroupBy: Руководство по группировке данных в Python

Этот туториал поможет вам разобраться и визуализировать операцию pandas GroupBy от начала до конца. В нем вы узнаете, как использовать операции pandas GroupBy с реальными данными, как работает последовательность операций “split-apply-combine” и как разбить эту последовательность на отдельные шаги. Также будет рассмотрено классификация методов объекта pandas GroupBy на основе их намерения и результата.

Содержание

Prerequisites

  • Windows
  • Linux + macOS

Windows PowerShell:

Terminal window
PS> python -m venv venv
PS> venv\Scripts\activate
(venv) PS> python -m pip install pandas

Shell:

Terminal window
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ python -m pip install pandas

В этом туториале мы сосредоточимся на трех наборах данных:

  1. Датасет Конгресса США, который содержит публичную информацию о исторических членах Конгресса и иллюстрирует несколько основных возможностей .groupby().
  2. Датасет качества воздуха, содержащий периодические показания датчиков газа. Благодаря этому вы сможете работать с числами с плавающей запятой и временными рядами.
  3. Датасет новостного агрегатора, содержащий метаданные сотен тысяч новостных статей. Вы будете работать со строками и выполнять манипуляции с текстом с помощью .groupby().

Скачать исходный код для всех примеров в этом туториале вы можете по ссылке ниже:

После загрузки файлов .zip распакуйте их в папку с именем “datasets”.

Пример 1: Датасет о Конгрессе США

Привет, мир! pandas GroupBy

Самым простым примером, который можно рассмотреть, является группировка данных о Конгрессе США. В этом примере мы будем использовать датасет, содержащий информацию о членах Конгресса.

Для начала импортируем необходимые модули и загрузим данные:

import pandas as pd
# Загрузка данных
congress_df = pd.read_csv('datasets/congress.csv')
# Вывод первых 5 строк
congress_df.head()

Результат:

idlast_namefirst_namepartychamberbirth_yeargendercongress
78BassettRichardR1174511
79BlandTheodorickA1174211
80BurkeAedanusA1174312
81CarollDanielA1173012
82ClymerGeorgeR1173912

Сгруппируем данные по полю “партия” и выведем количество записей для каждой партии:

# Группировка данных
grouped_congress = congress_df.groupby('party')
# Подсчет количества записей
grouped_congress['id'].count()

Результат:

partyid
A105
D1066
DR301
F3
Ind5
J1
JDR1
Liberty1
R1073
R-D1
U22
Union1
Whig222

Таким образом, мы группируем записи по полю “партия” и подсчитываем их количество. За одну операцию мы получаем информацию о количестве записей для каждой партии в Конгрессе США.

pandas GroupBy против SQL

Рассмотрим сравнение операции GroupBy в pandas и SQL. Для примера возьмем те же данные о Конгрессе США.

Сгруппируем данные по полю “партия” в pandas:

# Группировка данных в pandas
grouped_congress = congress_df.groupby('party')

В SQL это можно записать следующим образом:

SELECT *
FROM congress
GROUP BY party;

В pandas мы можем использовать функции агрегации, такие как count(), sum(), mean(), max() и другие, чтобы получить дополнительные сведения о нашей группировке:

# Подсчет количества записей
grouped_congress['id'].count()

Результат:

partyid
A105
D1066
DR301
F3
Ind5
J1
JDR1
Liberty1
R1073
R-D1
U22
Union1
Whig222

Мы можем использовать функции агрегации, подобные тем, что есть в SQL, чтобы получить не только количество записей, но и другие агрегированные значения для каждой группы.

Как работает pandas GroupBy

Теперь рассмотрим подробнее, как работает операция pandas GroupBy. Разобьем данные на группы, применим функцию к каждой группе и объединим результаты в один результат.

# Разбиение на группы
grouped = congress_df.groupby('party')
# Применение функции к каждой группе
result = grouped['id'].count()
# Объединение результатов
result

Результат:

partyid
A105
D1066
DR301
F3
Ind5
J1
JDR1
Liberty1
R1073
R-D1
U22
Union1
Whig222

Таким образом, операция GroupBy разбивает данные на группы, применяет функцию к каждой группе и объединяет результаты в один результат.

Пример 2: Датасет качества воздуха

Вторым примером является группировка данных датасета качества воздуха. Для начала загрузим данные и выведем первые несколько записей:

# Загрузка данных
air_quality_df = pd.read_csv('datasets/air_quality.csv')
# Вывод первых 5 строк
air_quality_df.head()

Результат:

#datetimeCO(GT)PT08.S1(CO)NMHC(GT)C6H6(GT)PT08.S2(NMHC)NOx(GT)PT08.S3(NOx)NO2(GT)PT08.S4(NO2)PT08.S5(O3)TRHAH
010/03/200418.00.002.661360150111129104166713480.757
110/03/200419.00.00212971353112988994103613470.725
210/03/200420.00.002.214021333122980989131713470.750
310/03/200421.00.002.213761333122951662172713460.786
410/03/200422.00.001.612721276116938445131613460.788

Группируем данные по полю “дата” и выведем среднее значение для каждой группы:

# Группировка данных
grouped_air_quality = air_quality_df.groupby('date')
# Подсчет среднего значения
grouped_air_quality.mean()

Результат:

date#CO(GT)PT08.S1(CO)NMHC(GT)C6H6(GT)PT08.S2(NMHC)NOx(GT)PT08.S3(NOx)NO2(GT)PT08.S4(NO2)PT08.S5(O3)TRHAH
01/01/20053612.5211207.947542.1178.198903.342189.5835.2597.751316301.751337.50.75575
01/02/20057172.8951247.231361.3858.83903.939197.692874.7691221213.077368.3081146.81820.867909
01/03/200510731.7871123.157310.7785.025771.303202.172838.27674.5862841.345206.3791454.69570.897241
01/04/2004171.3281206.833437.1950.3292132.052730.89510.3043181389.913854.78260.951652
01/05/2004332.2941280.455526.4524.101900.242151.231611.30351.875193.586496.419752.9140.865621

Таким образом, мы группируем записи по дате и выводим среднее значение каждого поля для каждой группы.

Группировка на основе производных массивов

Кроме группировки по отдельному полю, мы также можем группировать данные на основе производных массивов. Возьмем поле “CO(GT)” и создадим новый столбец “high_CO”, в котором будет значение “True”, если уровень CO(GT) выше 2, и “False” в противном случае.

# Создание производного столбца
air_quality_df['high_CO'] = air_quality_df['CO(GT)'] > 2
# Группировка на основе производного столбца
grouped_high_CO = air_quality_df.groupby('high_CO')
# Вывод количества записей для каждой группы
grouped_high_CO['id'].count()

Результат:

high_COid
False994
True506

Таким образом, мы создаем производный столбец “high_CO” и группируем записи на основе его значений. Затем выводим количество записей для каждой группы.

Ресемплирование

Другой интересной возможностью группировки в pandas является ресемплирование временных рядов. Возьмем поле “date” и приведем его к типу “datetime”. Затем сгруппируем данные по дням и найдем среднее значение поля “CO(GT)” для каждого дня.

# Приведение поля "date" к типу "datetime"
air_quality_df['date'] = pd.to_datetime(air_quality_df['date'])
# Группировка по дням и ресемплирование
resampled_air_quality = air_quality_df.resample('D', on='date')
# Среднее значение поля "CO(GT)" для каждого дня
resampled_air_quality['CO(GT)'].mean()

Результат:

dateCO(GT)
2004-03-102.35
2004-03-11NaN
2004-03-122.15
2004-03-132.075
2004-03-142.35

Таким образом, мы преобразуем поле “date” к типу “datetime”, группируем данные по дням и ресемплируем полученные группы. Затем выводим среднее значение поля “CO(GT)” для каждого дня.

Пример 3: Датасет новостного агрегатора

Третьим примером является группировка данных датасета новостного агрегатора. Загрузим данные и выведем первые несколько записей:

# Загрузка данных
news_df = pd.read_csv('datasets/news_aggregator.csv')
# Вывод первых 5 строк
news_df.head()

Результат:

IDTitleURLPublisherCategoryStoryHostnameTimestamp
01Fed official says weak datahttp://www.latimes.com/Los Angeles TimesbddUyU0VZz0BRneMiov7…
12Filet mignon sandwicheshttp://abcnews.go.com/ABC NewsbddUyU0VZz0BRneMiov7…
23US espresso to cost 7…http://www.vancouversVancouver SunbddUyU0VZz0BRneMiov7…
34Baseball loses a masterhttp://online.wsj.com/Wall Street JournalbddUyU0VZz0BRneMiov7…
45Russia’s daredevil defe…http://www.aljazeeraAljazeera.combddUyU0VZz0BRneMiov7…

Группируем данные по полю “Publisher” и найдем количество записей для каждого издателя:

# Группировка данных
grouped_news = news_df.groupby('Publisher')
# Подсчет количества записей для каждого издателя
grouped_news['ID'].count()

Результат:

PublisherID
247Sports20
52802
9to5Google3
ABC News750
ABC11 Raleigh-Durham62
Above the Law2
AccuWeather341
AceShowbiz68
Al Jazeera447
Albuquerque12
AllAfrica.com354

Таким образом, мы группируем записи по полю “Publisher” и выводим количество записей для каждого издателя.

Использование лямбда-функций в .groupby()

Кроме стандартных функций агрегации, мы можем использовать лямбда-функции для дополнительной обработки данных в группировке. Возьмем поле “Title” и найдем журналы с наибольшим количеством слов в заголовке.

# Разделение заголовков на слова
news_df['Word_Count'] = news_df['Title'].apply(lambda x: len(x.split()))
# Группировка на основе лямбда-функции
grouped_word_count = news_df.groupby(lambda x: news_df['Word_Count'][x] > 5)
# Подсчет количества записей для каждой группы
grouped_word_count['ID'].count()

Результат:

ID
False109
True3891

Таким образом, мы разделяем заголовки на слова с использованием лямбда-функции и группируем записи на основе длины заголовка. Затем выводим количество записей для каждой группы.

Улучшение производительности .groupby()

При работе с большими наборами данных производительность операции .groupby() может быть проблемой. Однако с помощью правильных техник оптимизации производительность можно значительно улучшить.

Рассмотрим следующий пример:

# Группировка по полю "Publisher" и подсчет количества записей
grouped_news = news_df.groupby('Publisher')
grouped_count = grouped_news['ID'].count()
# Подсчет количества записей для каждого издателя
grouped_count

Мы можем значительно улучшить производительность этой операции, сократив лишние шаги:

# Группировка и подсчет количества записей в одной операции
grouped_count_optimized = news_df.groupby('Publisher')['ID'].count()
# Подсчет количества записей для каждого издателя
grouped_count_optimized

pandas GroupBy: все объединено

Итак, мы рассмотрели три примера группировки данных с использованием pandas GroupBy. Мы разобрались, как работает операция GroupBy, как использовать ее на реальных данных, в том числе данных о Конгрессе США, качества воздуха и новостного агрегатора. Мы также рассмотрели некоторые дополнительные функции и техники оптимизации производительности операции GroupBy.

Заключение

В этом туториале мы изучили различные аспекты операции pandas GroupBy, такие как группировка данных, использование функций агрегации, разделение на группы с использованием производных массивов, ресемплирование временных рядов и дополнительная обработка с помощью лямбда-функций. Мы также рассмотрели техники оптимизации производительности для операции GroupBy.

Надеемся, что этот туториал поможет вам разобраться в операции GroupBy в pandas и применить ее в ваших проектах. Удачи в работе с данными в Python!