Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Васильев Ю. - Python для data science (Библиотека программиста) - 2023.pdf
Скачиваний:
7
Добавлен:
07.04.2024
Размер:
7.21 Mб
Скачать

6

Агрегирование данных

Зачастую данные необходимо агрегировать для того,

чтобы принимать взвешенные решения на их осно-

ве. Агрегирование — это процесс сбора данных для их

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

агрегирования, встроенные в pandas, и обсудим, как их можно использовать для анализа данных.

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

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

Данные для агрегирования      133

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

Данные для агрегирования

Чтобы посмотреть, как работает агрегирование, создадим набор датафреймов, содержащих информацию о продажах модной верхней одежды в онлайнмагазине. Эти данные будут включать номера и даты заказов; подробную информацию о товарах из каждого заказа (например, цену и количество); сотрудников, выполняющих каждый заказ, и местонахождение складов компании. В реальном приложении эти данные, скорее всего, будут храниться

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

вобъект DataFrame. Список кортежей можно загрузить из репозитория GitHub для этой книги.

Рассмотрим примеры заказов. Список с именем orders содержит несколько кортежей, каждый из которых представляет один заказ. Каждый кортеж содержит три поля: номер заказа, дату и уникальный номер (ID) сотрудника, который выполнил заказ:

orders = [

(9423517, '2022-02-04', 9001), (4626232, '2022-02-04', 9003), (9423534, '2022-02-04', 9001), (9423679, '2022-02-05', 9002), (4626377, '2022-02-05', 9003), (4626412, '2022-02-05', 9004), (9423783, '2022-02-06', 9002), (4626490, '2022-02-06', 9004)

]

Начнем с импортирования библиотеки pandas и преобразования списка в DataFrame:

import pandas as pd

df_orders = pd.DataFrame(orders, columns =['OrderNo', 'Date', 'Empno'])

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

134      Глава 6. Агрегирование данных

details, который мы преобразуем в еще один датафрейм. Каждый кортеж представляет собой строку заказа с полями, соответствующими номеру заказа, названию товара, бренду, цене и количеству:

details = [

(9423517, 'Jeans', 'Rip Curl', 87.0, 1), (9423517, 'Jacket', 'The North Face', 112.0, 1), (4626232, 'Socks', 'Vans', 15.0, 1),

(4626232, 'Jeans', 'Quiksilver', 82.0, 1), (9423534, 'Socks', 'DC', 10.0, 2), (9423534, 'Socks', 'Quiksilver', 12.0, 2), (9423679, 'T-shirt', 'Patagonia', 35.0, 1), (4626377, 'Hoody', 'Animal', 44.0, 1),

(4626377, 'Cargo Shorts', 'Animal', 38.0, 1), (4626412, 'Shirt', 'Volcom', 78.0, 1), (9423783, 'Boxer Shorts', 'Superdry', 30.0, 2), (9423783, 'Shorts', 'Globe', 26.0, 1), (4626490, 'Cargo Shorts', 'Billabong', 54.0, 1), (4626490, 'Sweater', 'Dickies', 56.0, 1)

]

# преобразуем список в DataFrame

df_details = pd.DataFrame(details, columns =['OrderNo', 'Item', 'Brand', 'Price', 'Quantity'])

Информацию о сотрудниках компании будем хранить в третьем датафрейме. Создадим его из списка кортежей emps, который содержит номера, имена и местоположение сотрудников:

emps = [

(9001, 'Jeff Russell', 'LA'),

(9002, 'Jane Boorman', 'San Francisco'), (9003, 'Tom Heints', 'NYC'),

(9004, 'Maya Silver', 'Philadelphia')

]

df_emps = pd.DataFrame(emps, columns =['Empno', 'Empname', 'Location'])

Наконец, у нас есть информация о городе и регионе каждого склада. Она хранится в списке кортежей с именем locations. Из этих данных формируем четвертый датафрейм:

locations = [

('LA', 'West'),

('San Francisco', 'West'), ('NYC', 'East'),

Объединение датафреймов      135

('Philadelphia', 'East')

]

df_locations = pd.DataFrame(locations, columns =['Location', 'Region'])

После преобразования данных в формат DataFrame их можно по-разному агрегировать, что позволит ответить на всевозможные вопросы о состоянии бизнеса. Например, можно просмотреть показатели продаж по различным регионам, генерируя промежуточные итоги на конкретную дату. Для этого сначала нужно объединить соответствующие данные в один датафрейм, затем распределить их по группам и применить к получившимся группам агрегатные функции.

Объединение датафреймов

Необходимые для агрегирования данные часто приходится собирать из множества различных контейнеров. Наш пример не исключение. Даже данные заказов распределены между двумя датафреймами: df_ordersи df_details. Наша цель — получить суммы продаж по регионам и по датам. Какие датафреймы нужно объединить и какие именно столбцы из них взять?

Поскольку нам нужен общий объем продаж, из df_detailsнужно взять колонки Price (цена) и Quantity (количество), из df_orders колонку Date (дата), а из df_locations Region (регион). Следовательно, необходимо объединить следующие датафреймы: df_orders, df_details и df_locations.

Датафреймы df_orders и df_details можно объединить непосредственно вызовом метода pandas merge(), как показано ниже:

df_sales = df_orders.merge(df_details)

ПРИМЕЧАНИЕ

Чтобыразобраться,какработаетmerge(),обратитеськразделу«Объединения «один-ко-многим»» в главе 3.

Мы объединяем датафреймы по столбцу OrderNo (номер заказа). Указывать это в явном виде необязательно, поскольку OrderNo присутствует в обоих датафреймах и будет выбран по умолчанию. Объединенный датафрейм теперь содержит одну запись для каждой строки заказа, как в df_details, но теперь вместе с информацией, добавленной из соответствующих записей из df_orders.

136      Глава 6. Агрегирование данных

Чтобы увидеть записи в объединенном датафрейме, можно просто вывести его на экран:

print(df_sales)

Содержимое df_sales будет выглядеть следующим образом:

 

OrderNo

Date

Empno

Item

Brand

Price

Quantity

0

9423517

2022-02-04

9001

Jeans

Rip Curl

87.0

1

1

9423517

2022-02-04

9001

Jacket

The North Face

112.0

1

2

4626232

2022-02-04

9003

Socks

Vans

15.0

1

3

4626232

2022-02-04

9003

Jeans

Quiksilver

82.0

1

4

9423534

2022-02-04

9001

Socks

DC

10.0

2

5

9423534

2022-02-04

9001

Socks

Quiksilver

12.0

2

6

9423679

2022-02-05

9002

T-shirt

Patagonia

35.0

1

7

4626377

2022-02-05

9003

Hoody

Animal

44.0

1

8

4626377

2022-02-05

9003

Cargo Shorts

Animal

38.0

1

9

4626412

2022-02-05

9004

Shirt

Volcom

78.0

1

10

9423783

2022-02-06

9002

Boxer Shorts

Superdry

30.0

2

11

9423783

2022-02-06

9002

Shorts

Globe

26.0

1

12

4626490

2022-02-06

9004

Cargo Shorts

Billabong

54.0

1

13

4626490

2022-02-06

9004

Sweater

Dickies

56.0

1

 

 

 

 

 

 

 

 

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

df_sales['Total'] = df_sales['Price'] * df_sales['Quantity']

Этот код добавит новый столбец Total (общая сумма) к датафрейму, в дополнение к семи существующим. Теперь у нас есть возможность удалить столбцы, которые не понадобятся для генерации суммы продаж по регионам и датам. На данном этапе необходимо сохранить только столбцы Date, Total и Empno (номер сотрудника). Первые два очевидно нужны для расчетов. А необходимость Empno мы обсудим в ближайшее время.

Чтобы отфильтровать датафрейм, сохранив только нужные столбцы, передадим список названий столбцов в оператор [] датафрейма, как показано ниже:

df_sales = df_sales[['Date','Empno','Total']]

Объединение датафреймов      137

Теперь нужно объединить датафрейм df_sales, который мы только что создали, и датафрейм df_regions. Однако не получится объединить их напрямую, потому что у них нет общих столбцов. Вместо этого объединим их через датафрейм df_emps, который имеет один общий столбец с df_sales и один — с df_regions. В частности, df_sales и df_emps можно объединить по столбцу Empno, именно поэтому мы сохранили данный столбец в df_sales, а df_emps и df_locations объединяются по столбцу Location (местоположение). Реализуем объединение с помощью метода merge():

df_sales_emps = df_sales.merge(df_emps) df_result = df_sales_emps.merge(df_locations)

Выводим датафрейм df_result:

 

Date

Empno

Total

Empname

Location Region

0

2022-02-04

9001

87.0

Jeff Russell

LA

West

1

2022-02-04

9001

112.0

Jeff Russell

LA

West

2

2022-02-04

9001

20.0

Jeff Russell

LA

West

3

2022-02-04

9001

24.0

Jeff Russell

LA

West

4

2022-02-04

9003

15.0

Tom Heints

NYC

East

5

2022-02-04

9003

82.0

Tom Heints

NYC

East

6

2022-02-05

9003

44.0

Tom Heints

NYC

East

7

2022-02-05

9003

38.0

Tom Heints

NYC

East

8

2022-02-05

9002

35.0

Jane Boorman

San Francisco

West

9

2022-02-06

9002

60.0

Jane Boorman

San Francisco

West

10

2022-02-06

9002

26.0

Jane Boorman

San Francisco

West

11

2022-02-05

9004

78.0

Maya Silver

Philadelphia

East

12

2022-02-06

9004

54.0

Maya Silver

Philadelphia

East

13

2022-02-06

9004

56.0

Maya Silver

Philadelphia

East

 

 

 

 

 

 

 

И снова вы, возможно, захотите удалить ненужные столбцы и оставить только те, которые действительно полезны. На этот раз можно избавиться от Empno,

Empname и Location, оставив только Date, Region и Total:

df_result = df_result[['Date','Region','Total']]

Теперь содержимое df_result выглядит следующим образом:

 

Date Region

Total

0

2022-02-04

West

87.0

1

2022-02-04

West

112.0

2

2022-02-04

West

20.0

3

2022-02-04

West

24.0