Python сводные таблицы – Полное руководство

Вы, возможно, знакомы с использованием сводных таблиц в Excel для быстрого получения информации из ваших данных. В этом посте вы узнаете, как создать сводные таблицы в Python и Pandas с использованием метода .pivot_table(). Этот пост даст вам полное представление о том, как использовать функцию

Быстрое суммирование данных является важным навыком, позволяющим получить представление о том, как выглядят ваши данные. Данная функция имеет много общего с методом .groupby(), также доступным в Pandas, но предлагает значительно больше возможностей настройки, как мы увидим далее в этом посте.

К концу этого руководства вы научитесь:

  • Как использовать функцию pivot_table() и что представляют собой ее параметры

  • Как сгруппировать данные с помощью индекса или мультииндекса

  • Как еще больше повернуть таблицу, используя индексы и столбцы

  • Как указать и создать собственные методы агрегации

  • Как подсчитать итоги и справиться с недостающими данными

Содержание

Как построить сводную таблицу в Python

Сводная таблица - это таблица статистики, которая помогает суммировать данные большей таблицы путем "поворота" этих данных. Microsoft Excel сделал сводные таблицы популярными, где они известны как PivotTables. Библиотека Pandas предоставляет возможность создавать сводные таблицы в Python с использованием функции .pivot_table(). Функция имеет следующие параметры по умолчанию:

# Синтаксис функции .pivot_table()
import pandas as pd
pd.pivot_table(
    data=,
    values=None, 
    index=None, 
    columns=None, 
    aggfunc='mean', 
    fill_value=None, 
    margins=False, 
    dropna=True, 
    margins_name='All', 
    observed=False,
    sort=True
)

Метод принимает DataFrame, а затем также возвращает DataFrame. В таблице ниже представлен обзор различных параметров, доступных в функции:

ПараметрЗначение по умолчаниюОписание

data=

DataFrame для поворота

values=

Столбец для агрегирования (если он пуст, будут агрегированы все числовые значения).

index=

Столбец или столбцы, по которым группируются данные. Один столбец может быть строкой, а несколько столбцов должны представлять собой список строк.

columns=

Столбец или столбцы, по которым группируются данные. Один столбец может быть строкой, а несколько столбцов должны представлять собой список строк.

aggfunc=

‘mean’

Функция или список функций для агрегирования данных по

fill_value=

Значение для замены отсутствующих значений

margins=

False

Добавьте строку и столбец для итогов

dropna=

True

Чтобы не включать столбцы, в которых все записи имеют значение NaN.

margins_name=

‘All’

Название итоговой строки/столбца

observed=

False

Только для категориальных данных — если True, будут отображаться только наблюдаемые значения для категориальных групп.

sort=

True

Сортировать ли полученные значения

Функция, по-разному, работает над преобразованием большого набора данных в широкий, но также предоставляет агрегации. Для выполнения обратной операции можно использовать функцию Pandas melt(), которая преобразует широкий DataFrame в длинный

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

Загрузка образца DataFrame Pandas

Чтобы следовать этому уроку, давайте загрузим пример DataFrame Pandas. Мы можем загрузить DataFrame из файла, размещенного на моей странице GitHub, используя функцию pd.read_excel(). Затем мы можем распечатать первые пять записей набора данных, используя метод

# Загрузка примера DataFrame в Pandas
import pandas as pd
df = pd.read_excel('https://github.com/BeMindYou/Lesson/raw/main/Data/sample_pivot.xlsx', parse_dates=['Date'])
print(df.head())

# Возвращает:
#         Date Region                 Type  Units  Sales
# 0 2020-07-11   East  Children's Clothing   18.0    306
# 1 2020-09-23  North  Children's Clothing   14.0    448
# 2 2020-04-02  South     Women's Clothing   17.0    425
# 3 2020-02-28   East  Children's Clothing   26.0    832
# 4 2020-03-19   West     Women's Clothing    3.0     33

Основываясь на выводе первых пяти строк, показанных выше, мы видим, что у нас есть пять столбцов для работы:

Имя столбцаОписание

Date

Дата транзакции

Region

Регион сделки

Type

Тип продаваемой одежды

Units

Количество проданных единиц

Sales

Стоимость продажи

Теперь, когда у нас есть немного больше контекста данных, давайте рассмотрим создание нашей первой сводной таблицы в Pandas.

Создание сводной таблицы в Pandas

Создадим вашу первую сводную таблицу Pandas. Как минимум, мы должны передать какой-либо ключ группировки, используя параметры index= или columns=. В приведенных ниже примерах мы используем функцию Pandas, а не функцию DataFrame. По этой причине нам нужно передать аргумент data=. Если бы мы применили метод непосредственно к DataFrame, это было бы подразумеваемо.

# Создание вашей первой сводной таблицы в Pandas
pivot = pd.pivot_table(
    data=df,
    index='Region'
)
print(pivot)

# Возвращает:
#              Sales      Units
# Region                       
# East    408.182482  19.732360
# North   438.924051  19.202643
# South   432.956204  20.423358
# West    452.029412  19.29411

Давайте разберем, что здесь произошло:

  1. Мы создали новый DataFrame под названием sales_by_region, который был создан с использованием функции

  2. Мы передали наш DataFrame, df, и установили index='region', что означает, что данные будут сгруппированы по столбцу региона

Ввиду того, что все остальные параметры были оставлены по умолчанию, библиотека Pandas сделала следующее предположение:

  • Данные должны агрегироваться по среднему значению каждого столбца

  • Значения должны быть любыми числовыми столбцами

Агрегирование только определенных столбцов в сводной таблице Pandas

В приведенном выше примере вы не изменили параметр values=. Из-за этого были агрегированы все числовые столбцы. Это может быть не всегда идеальным решением. По этой причине Pandas позволяет нам передавать либо одну строку, представляющую один столбец, либо список строк, представляющих несколько столбцов.

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

# Агрегирование только одного столбца
pivot = pd.pivot_table(
    data=df,
    index='Region',
    values='Sales'
)

print(pivot)

# Возвращает:
#              Sales
# Region            
# East    408.182482
# North   438.924051
# South   432.956204
# West    452.029412

Вместо того, чтобы агрегировать все числовые столбцы, был агрегирован только указанный столбец.

Работа с методами агрегирования в сводной таблице Pandas

Теперь, когда вы создали свою первую сводную таблицу в Pandas, давайте работать над изменением методов агрегации. Это позволяет вам указать, как вы хотите агрегировать свои данные. Именно здесь проявляется мощь Pandas, позволяя вам легко проводить сложные анализы.

Указание метода агрегирования в сводной таблице Pandas

Вы можете использовать параметр aggfunc= (функция агрегирования) для изменения способа агрегирования данных в сводной таблице. По умолчанию Pandas будет использовать метод .mean() для агрегирования данных. Вы можете передать именованную функцию, такую как 'mean', 'sum', или 'max', или вызываемую функцию, такую как

Давайте теперь попробуем изменить наше поведение, чтобы получить сумму наших продаж по всем регионам:

# Указание функции агрегации
pivot = pd.pivot_table(
    data=df,
    index='Region',
    aggfunc='sum'
)

print(pivot)

# Возвращает:
#          Sales   Units
# Region                
# East    167763  8110.0
# North   138700  4359.0
# South    59315  2798.0
# West     61476  2624.0

Множественный Метод Агрегирования в Pandas DataFrame

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

# Указание нескольких функций агрегации
pivot = pd.pivot_table(
    data=df,
    index='Region',
    aggfunc=['mean', 'sum']
)

print(pivot)

# Возвращает:
#               mean                sum        
#              Sales      Units   Sales   Units
# Region                                       
# East    408.182482  19.732360  167763  8110.0
# North   438.924051  19.202643  138700  4359.0
# South   432.956204  20.423358   59315  2798.0
# West    452.029412  19.294118   61476  2624.0

Мы можем видеть, насколько это было легко и сколько дополнительных данных теперь доступно! Для каждого столбца с числовыми данными создаются как среднее значение, так и сумма.

Указание Различных Агрегаций для Каждого Столбца

Чтобы рассчитать различные агрегации по каждому столбцу, можно передать словарь в следующем формате ключ-значение: 'столбец': функция. Допустим, мы хотим рассчитать сумму единиц и среднее количество продаж:

# Указание функций агрегации для разных столбцов
pivot = pd.pivot_table(
    data=df,
    index='Region',
    aggfunc={'Sales': 'mean', 'Units': 'sum'}
)

print(pivot)

# Возвращает:
#              Sales   Units
# Region                    
# East    408.182482  8110.0
# North   438.924051  4359.0
# South   432.956204  2798.0
# West    452.029412  2624.0

Это позволяет вам легко сравнивать данные по различным ключевым показателям эффективности в одном DataFrame.

Пользовательские агрегации в сводных таблицах Pandas

Pandas позволяет также передавать в функцию .pivot_table() пользовательские функции. Это значительно расширяет наши возможности для проведения анализов, точно настроенных под ваши потребности! Давайте посмотрим, как мы можем передать функцию, которая вычисляет среднее значение колонки без выбросов.

Pandas предоставляет метод .quantile(), который позволяет нам определить диапазон значений, которые мы хотим выбрать на основе их процентного соотношения в диапазоне данных. Допустим, мы хотели бы рассчитать среднее значение столбца, исключая верхние и нижние 10% данных. Мы могли бы определить следующую функцию:

# Определение пользовательской функции
import numpy as np

def mean_no_outliers(values):
    no_outliers = values.quantile([0.1, 0.9])
    mean = np.mean(no_outliers)
    return mean

Эта функция принимает один параметр, values, который будет передан функцией .pivot_table(). Затем значения фильтруются с помощью метода .quantile(). В конце вычисляется среднее значение этих данных. Давайте посмотрим, как мы можем использовать это (и обычную агрегацию mean) в нашей сводной таблице, применённой к нашему столбцу Sales.

# Указание пользовательских функций в сводной таблице Pandas
pivot = pd.pivot_table(
    data=df,
    index='Region',
    aggfunc=['mean', mean_no_outliers],
    values='Sales'
)

print(pivot)

# Возвращает:
#               mean mean_no_outliers
#              Sales            Sales
# Region                             
# East    408.182482            436.0
# North   438.924051            484.5
# South   432.956204            434.1
# West    452.029412            497.0

Более сложные сводные таблицы Pandas

Теперь, когда вы поняли, как работает функция .pivot_table() в Pandas, давайте посмотрим, как мы можем расширить наше понимание. В этом разделе вы узнаете, как добавлять колонки и множественные индексы к нашим сводным таблицам в Pandas.

Добавление столбцов к сводной таблице Pandas

При добавлении столбцов в сводную таблицу Pandas мы добавляем к данным еще одно измерение. В то время как параметр index= делит данные по вертикали, параметр columns= группирует данные и разделяет их по горизонтали. Это позволяет нам создать легко читаемую таблицу. Давайте посмотрим, как мы можем использовать параметр columns= для разделения данных по столбцу Type.

# Добавление столбцов в нашу сводную таблицу Pandas
pivot = pd.pivot_table(
    data=df,
    index='Region',
    columns='Type',
    values='Sales'
)

print(pivot)

# Возвращает:
# Type    Children's Clothing  Men's Clothing  Women's Clothing
# Region                                                       
# East             405.743363      423.647541        399.028409
# North            438.894118      449.157303        432.528169
# South            412.666667      475.435897        418.924528
# West             480.523810      465.292683        419.188679

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

Добавление нескольких индексов в сводные таблицы Pandas

Добавление множественных индексов с иерархией данных

В добавок к добавлению горизонтального измерения с помощью колонок, мы также можем определить множественные индексы, когда в наших данных присутствует логическая иерархия. Например, мы можем добавить измерение даты к нашей сводной таблице. Давайте использовать встроенные в Pandas аксессоры даты для группировки наших данных по кварталам. Это позволит нам визуализировать наши данные за определенный период времени. Давайте посмотрим, как это работает:

# Создание сводной таблицы с мультииндексом
pivot = pd.pivot_table(
    data=df,
    index=['Region', df['Date'].dt.quarter],
    columns='Type',
    values='Sales'
)

print(pivot.head())

# Возвращает:
# Type         Children's Clothing  Men's Clothing  Women's Clothing
# Region Date                                                       
# East   1              423.241379      369.250000        428.948718
#        2              274.800000      445.425000        456.816327
#        3              425.382353      506.421053        342.386364
#        4              453.866667      405.666667        364.795455
# North  1              394.727273      450.869565        489.944444

Это возвращает DataFrame Pandas с мультииндексом. Хотя это может выглядеть сложнее, доступ к данным в DataFrame Pandas с мультииндексом работает довольно похожим образом, как и доступ к данным в любом другом DataFrame. Однако, поскольку теперь у нас есть два индексных столбца, а не один, мы можем передать кортеж индексов. Допустим, мы хотели бы получить доступ только к пересечению Восточного региона, Первого квартала и Мужской одежды, мы могли бы использовать следующий код:

# Доступ к данным в мультииндексной сводной таблице
print(pivot.loc[('East', 1), "Men's Clothing"])

# Возвращает: 369.25

Настройка сводных таблиц Pandas

Настройка сводных таблиц Pandas

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

Добавление Итогов к Сводным Таблицам Pandas

Добавление итогов к таблице сводки в Pandas управляется параметром margins=, который принимает булево значение. По умолчанию этот параметр установлен в False, но если его изменить на True, то к строкам и столбцам будут добавлены итоги. Давайте посмотрим, как это выглядит:

# Добавление итогов по строкам и столбцам
pivot = pd.pivot_table(
    data=df,
    index='Region',
    columns='Type',
    values='Sales',
    margins=True
)

print(pivot)

# Возвращает:
# Type    Children's Clothing  Men's Clothing  Women's Clothing         All
# Region                                                                   
# East             405.743363      423.647541        399.028409  408.182482
# North            438.894118      449.157303        432.528169  438.924051
# South            412.666667      475.435897        418.924528  432.956204
# West             480.523810      465.292683        419.188679  452.029412
# All              427.743860      444.257732        415.254717  427.254000

По умолчанию Pandas называет итоговые значения 'All'. Если вы хотите переименовать эти метки, можно использовать параметр margins_name=, чтобы передать строку для переименования значений.

# Переименование итогов в сводной таблице Pandas
pivot = pd.pivot_table(
    data=df,
    index='Region',
    columns='Type',
    values='Sales',
    margins=True,
    margins_name='Total'
)

print(pivot)

# Возвращает:
# Type    Children's Clothing  Men's Clothing  Women's Clothing       Total
# Region                                                                   
# East             405.743363      423.647541        399.028409  408.182482
# North            438.894118      449.157303        432.528169  438.924051
# South            412.666667      475.435897        418.924528  432.956204
# West             480.523810      465.292683        419.188679  452.029412
# Total            427.743860      444.257732        415.254717  427.254000

Обработка пропущенных данных в сводной таблице Pandas

Когда Pandas сталкивается с пересечением, где отсутствуют данные, он включает значение NaN в полученную сводную таблицу. Давайте модифицируем наш DataFrame, чтобы включить некоторые пропущенные данные, и вычислим сводную таблицу, чтобы увидеть, как это выглядит:

# Добавление и просмотр отсутствующих данных в сводной таблице Pandas
import numpy as np
df.loc[(df['Region'] == 'East') & (df['Type'] == "Children's Clothing"), 'Sales'] = np.NaN

pivot = pd.pivot_table(
    data=df,
    index='Region',
    columns='Type',
    values='Sales',
)

print(pivot)

# Возвращает:
# Type    Children's Clothing  Men's Clothing  Women's Clothing
# Region                                                       
# East                    NaN      423.647541        399.028409
# North            438.894118      449.157303        432.528169
# South            412.666667      475.435897        418.924528
# West             480.523810      465.292683        419.188679

Возможность увидеть значение NaN может быть не всегда идеальной, особенно для не технической аудитории. Именно по этой причине Pandas предлагает параметр fill_value=, который позволяет вам передать значение для заполнения этих пропущенных данных. Например, если мы хотим заполнить все эти значения нулями, мы можем просто передать этот аргумент:

# Заполнение отсутствующих значений в сводной таблице Pandas
import numpy as np
df.loc[(df['Region'] == 'East') & (df['Type'] == "Children's Clothing"), 'Sales'] = np.NaN

pivot = pd.pivot_table(
    data=df,
    index='Region',
    columns='Type',
    values='Sales',
    fill_value=0
)

print(pivot)

# Возвращает:
# Type    Children's Clothing  Men's Clothing  Women's Clothing
# Region                                                       
# East               0.000000      423.647541        399.028409
# North            438.894118      449.157303        432.528169
# South            412.666667      475.435897        418.924528
# West             480.523810      465.292683        419.188679

Сортировка данных в сводной таблице Pandas

Начиная с версии Pandas 1.3.0, был добавлен новый параметр, который позволяет сортировать получаемый DataFrame. Раньше для этого необходимо было сначала создать DataFrame, а затем применить метод для сортировки данных. Теперь можно просто использовать аргумент sort=True, чтобы отсортировать получаемый DataFrame.

# Сортировка сводной таблицы Pandas
pivot = pd.pivot_table(
    data=df,
    index='Region',
    values='Sales',
    sort=True
)

print(pivot)

# Возвращает:
#              Sales
# Region            
# East    408.182482
# North   438.924051
# South   432.956204
# West    452.029412

По умолчанию Pandas будет сортировать сводную таблицу в порядке возрастания. К сожалению, для более сложной сортировки (например, по разным столбцам) вам все равно придется использовать метод

Фильтрация сводных таблиц Python

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

# Генерация длинной сводной таблицы
pivot = pd.pivot_table(
    data=df,
    index=['Region', df['Date'].dt.quarter],
    values='Sales'
)

print(pivot.head())

# Возвращает:
#                   Sales
# Region Date            
# East   1     406.692308
#        2     419.238532
#        3     403.608247
#        4     402.178218
# North  1     462.142857

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

print(pivot[pivot['Sales'] > pivot['Sales'].mean()])

# Возвращает:
#                   Sales
# Region Date            
# North  1     462.142857
#        2     442.034884
#        3     447.200000
# South  1     465.263158
#        2     440.628571
# West   1     475.000000
#        3     444.884615
#        4     466.209302

Это позволяет нам видеть именно то, что мы хотим видеть!

Упражнения

Пришло время проверить ваши знания! Попробуйте решить приведенные ниже упражнения, опираясь на то, что вы узнали. Если вам нужна помощь или вы хотите проверить свое решение, раскройте раздел, чтобы увидеть образец решения. Используйте тот же DataFrame, что и во всем учебнике.

  • Question 1

  • Question 2

  • Question 3

Как удалить строку с итогами (все) из сводной таблицы?

Иногда вам может потребоваться получить только итоги по столбцам в вашем итоговом DataFrame. В этом случае вы можете просто отфильтровать последнюю строку, используя отрицательный индекс:

pivot.loc[-1:,]

Какое значение может быть не лучшим выбором в качестве параметра fill_value и почему?

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

В каком регионе были самые высокие продажи DataFrame? Как бы вы получили название региона программно?

Вы можете отсортировать свою сводную таблицу, а затем использовать аксессор .index для доступа к последнему значению (так как данные отсортированы в порядке возрастания).

pivot = pd.pivot_table(
    data=df,
    index='Region',
    values='Sales',
    sort=True
)

print(pivot.index[-1])

# Возвращает: West

Заключение и резюме

В этом уроке вы научились использовать функцию .pivot_table() в Pandas для создания сводных таблиц в стиле Excel непосредственно из DataFrame в Pandas. Функция предоставляет значительную гибкость за счет большого ассортимента параметров. Ниже представлено краткое описание того, что вы узнали:

  • Функция pivot_table() в библиотеке Pandas предоставляет привычный интерфейс для создания сводных таблиц в стиле Excel.

  • Функция требует указания как минимум одного из параметров: index= или columns=, для определения способа разделения данных.

  • Функция может выполнять один или несколько методов агрегирования, включая использование пользовательских функций.

  • Функция возвращает DataFrame, который может быть отфильтрован или запрошен так же, как и любой другой DataFrame.

Дополнительные ресурсы

Чтобы узнать больше о смежных темах, ознакомьтесь с нижеприведенными учебными пособиями:

Last updated