Опануйте реформування даних за допомогою зведених таблиць Python Pandas. Глибокий аналіз синтаксису, передових технік і практичних прикладів для глобального аналізу даних.
Python Pandas Зведені таблиці: Комплексний посібник з реформування даних
У світі аналізу даних здатність підсумовувати, агрегувати та реструктуризувати дані - це не просто навичка, це суперсила. Необроблені дані, у їхній первісній формі, часто нагадують розлогий, детальний реєстр. Він багатий на інформацію, але важкий для інтерпретації. Щоб отримати значущі висновки, нам потрібно перетворити цей реєстр на стислий підсумок. Саме тут чудово показують себе зведені таблиці, а для програмістів Python бібліотека Pandas надає потужний і гнучкий інструмент: pivot_table().
Цей посібник розроблено для глобальної аудиторії аналітиків даних, науковців і ентузіастів Python. Ми глибоко зануримося в механіку зведених таблиць Pandas, переходячи від фундаментальних концепцій до передових методів. Незалежно від того, чи підсумовуєте ви показники продажів з різних континентів, аналізуєте кліматичні дані по регіонах, чи відстежуєте показники проєкту для розподіленої команди, опанування зведених таблиць кардинально змінить ваш підхід до дослідження даних.
Що таке зведена таблиця?
Якщо ви коли-небудь використовували програмне забезпечення для роботи з електронними таблицями, як-от Microsoft Excel або Google Sheets, ви, ймовірно, знайомі з концепцією зведеної таблиці. Це інтерактивна таблиця, яка дозволяє реорганізовувати та підсумовувати вибрані стовпці та рядки даних із більшого набору даних, щоб отримати бажаний звіт.
Зведена таблиця робить дві ключові речі:
- Агрегація: Обчислює підсумкову статистику (наприклад, суму, середнє значення або кількість) для числових даних, згрупованих за однією або кількома категоріями.
- Реформування: Перетворює дані з "довгого" формату в "широкий" формат. Замість того, щоб мати всі значення в одному стовпці, він "зводить" унікальні значення зі стовпця в нові стовпці у вихідних даних.
Функція Pandas pivot_table() надає цю потужну функціональність безпосередньо у ваш робочий процес аналізу даних Python, забезпечуючи відтворюване, скриптоване та масштабоване реформування даних.
Налаштування середовища та зразка даних
Перш ніж ми почнемо, переконайтеся, що у вас встановлено бібліотеку Pandas. Якщо ні, ви можете встановити її за допомогою pip, інсталятора пакетів Python:
pip install pandas
Тепер давайте імпортуємо її в наш сценарій Python або блокнот:
import pandas as pd
import numpy as np
Створення глобального набору даних про продажі
Щоб зробити наші приклади практичними та глобально релевантними, ми створимо синтетичний набір даних, що представляє дані про продажі для багатонаціональної компанії електронної комерції. Цей набір даних міститиме інформацію про продажі з різних регіонів, країн і категорій продуктів.
# Create a dictionary of data
data = {
'TransactionID': range(1, 21),
'Date': pd.to_datetime([
'2023-01-15', '2023-01-16', '2023-01-17', '2023-02-10', '2023-02-11',
'2023-02-12', '2023-03-05', '2023-03-06', '2023-03-07', '2023-01-20',
'2023-01-21', '2023-02-15', '2023-02-16', '2023-03-10', '2023-03-11',
'2023-01-18', '2023-02-20', '2023-03-22', '2023-01-25', '2023-02-28'
]),
'Region': [
'North America', 'Europe', 'Asia', 'North America', 'Europe', 'Asia', 'North America', 'Europe', 'Asia', 'Europe',
'Asia', 'North America', 'Europe', 'Asia', 'North America', 'Asia', 'Europe', 'North America', 'Europe', 'Asia'
],
'Country': [
'USA', 'Germany', 'Japan', 'Canada', 'France', 'India', 'USA', 'UK', 'China', 'Germany',
'Japan', 'USA', 'France', 'India', 'Canada', 'China', 'UK', 'USA', 'Germany', 'India'
],
'Product_Category': [
'Electronics', 'Apparel', 'Electronics', 'Books', 'Apparel', 'Electronics', 'Books', 'Electronics', 'Apparel',
'Apparel', 'Books', 'Electronics', 'Books', 'Apparel', 'Electronics', 'Books', 'Apparel', 'Books', 'Electronics', 'Electronics'
],
'Units_Sold': [10, 5, 8, 20, 7, 12, 15, 9, 25, 6, 30, 11, 18, 22, 14, 28, 4, 16, 13, 10],
'Unit_Price': [1200, 50, 900, 15, 60, 1100, 18, 950, 45, 55, 12, 1300, 20, 40, 1250, 14, 65, 16, 1150, 1050]
}
# Create DataFrame
df = pd.DataFrame(data)
# Calculate Revenue
df['Revenue'] = df['Units_Sold'] * df['Unit_Price']
# Display the first few rows of the DataFrame
print(df.head())
Цей набір даних дає нам міцну основу із суміші категоріальних даних (Регіон, Країна, Категорія_продукту), числових даних (Продані_одиниці, Дохід) і даних часових рядів (Дата).
Анатомія pivot_table()
Функція Pandas pivot_table() неймовірно універсальна. Давайте розберемо її найважливіші параметри:
pandas.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, margins_name='All')
- data: DataFrame, який потрібно звести.
- values: Стовпець(ці), що містить дані для агрегування. Якщо не вказано, використовуватимуться всі числові стовпці, що залишилися.
- index: Стовпець(ці), унікальні значення яких утворюватимуть рядки нової зведеної таблиці. Це іноді називають "ключем групування".
- columns: Стовпець(ці), унікальні значення яких будуть "зведені", щоб утворити стовпці нової таблиці.
- aggfunc: Функція агрегування, яку потрібно застосувати до "значень". Це може бути рядок, наприклад "sum", "mean", "count", "min", "max", або функція, наприклад
np.sum. Ви також можете передати список функцій або словник, щоб застосувати різні функції до різних стовпців. За замовчуванням використовується значення "mean". - fill_value: Значення для заміни будь-яких відсутніх результатів (NaN) у зведеній таблиці.
- margins: Логічне значення. Якщо встановлено значення
True, додає проміжні підсумки для рядків і стовпців (також відомі як загальний підсумок). - margins_name: Назва для рядка/стовпця, що містить підсумки, коли
margins=True. За замовчуванням використовується значення "All".
Ваша перша зведена таблиця: простий приклад
Давайте почнемо з поширеного бізнес-питання: "Який загальний дохід, отриманий кожною категорією продуктів?"
Щоб відповісти на це, нам потрібно:
- Використовуйте
Product_Categoryдля рядків (index). - Агрегуйте стовпець
Revenue(values). - Використовуйте суму як нашу функцію агрегування (aggfunc).
# Simple pivot table to see total revenue by product category
category_revenue = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
aggfunc='sum')
print(category_revenue)
Вивід:
Revenue
Product_Category
Apparel 1645
Books 1184
Electronics 56850
Миттєво ми отримуємо чіткий, стислий підсумок. Необроблений журнал транзакцій із 20 рядків було перетворено на таблицю з 3 рядків, яка безпосередньо відповідає на наше питання. Це фундаментальна сила зведеної таблиці.
Додавання виміру стовпця
Тепер давайте розширимо це. Що, якщо ми хочемо побачити загальний дохід за категоріями продуктів, але також розбити його за регіонами? Ось тут у гру вступає параметр columns.
# Pivot table with index and columns
revenue_by_category_region = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
columns='Region',
aggfunc='sum')
print(revenue_by_category_region)
Вивід:
Region Asia Europe North America Product_Category Apparel 1125.0 625.0 NaN Books 336.0 360.0 488.0 Electronics 13200.0 14550.0 29100.0
Цей вивід набагато багатший. Ми звели унікальні значення зі стовпця "Регіон" ("Азія", "Європа", "Північна Америка") в нові стовпці. Тепер ми можемо легко порівняти, як різні категорії продуктів працюють у різних регіонах. Ми також бачимо значення NaN (Не число). Це вказує на те, що в нашому наборі даних не було зафіксовано жодного продажу "Одягу" для "Північної Америки". Це само по собі є цінною інформацією!
Передові методи зведення
Основи є потужними, але справжня гнучкість pivot_table() розкривається в її розширених функціях.
Обробка відсутніх значень за допомогою fill_value
NaN у нашій попередній таблиці є точним, але для звітності або подальших обчислень може бути краще відображати його як нуль. Параметр fill_value робить це простим.
# Using fill_value to replace NaN with 0
revenue_by_category_region_filled = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
columns='Region',
aggfunc='sum',
fill_value=0)
print(revenue_by_category_region_filled)
Вивід:
Region Asia Europe North America Product_Category Apparel 1125 625 0 Books 336 360 488 Electronics 13200 14550 29100
Тепер таблиця чистіша та легша для читання, особливо для нетехнічної аудиторії.
Робота з кількома індексами (ієрархічне індексування)
Що, якщо вам потрібно згрупувати за кількома категоріями в рядках? Наприклад, давайте розіб'ємо продажі за Region, а потім за Country у кожному регіоні. Ми можемо передати список стовпців параметру index.
# Multi-level pivot table using a list for the index
multi_index_pivot = pd.pivot_table(df,
values='Revenue',
index=['Region', 'Country'],
aggfunc='sum',
fill_value=0)
print(multi_index_pivot)
Вивід:
Revenue
Region Country
Asia China 488
India 1760
Japan 10860
Europe France 1020
Germany 14440
UK 1115
North America Canada 17800
USA 12058
Pandas автоматично створив MultiIndex у рядках. Ця ієрархічна структура чудово підходить для деталізації даних і перегляду вкладених зв'язків. Ви можете застосувати ту саму логіку до параметра columns, щоб створити ієрархічні стовпці.
Використання кількох функцій агрегування
Іноді однієї підсумкової статистики недостатньо. Можливо, ви захочете побачити як загальний дохід (суму), так і середній розмір транзакції (середнє значення) для кожної групи. Ви можете передати список функцій aggfunc.
# Using multiple aggregation functions
multi_agg_pivot = pd.pivot_table(df,
values='Revenue',
index='Region',
aggfunc=['sum', 'mean', 'count'])
print(multi_agg_pivot)
Вивід:
sum mean count
Revenue Revenue Revenue
Region
Asia 13108.000000 2184.666667 6
Europe 16575.000000 2762.500000 6
North America 29858.000000 4976.333333 6
Ця єдина команда дає нам вичерпний підсумок: загальний дохід, середній дохід на транзакцію та кількість транзакцій для кожного регіону. Зверніть увагу, як Pandas створює ієрархічні стовпці для підтримки організованості виводу.
Застосування різних функцій до різних значень
Ви можете отримати ще більше гранулярності. Уявіть, що ви хочете побачити суму Revenue, але середнє значення Units_Sold. Ви можете передати словник aggfunc, де ключі є назвами стовпців ("values"), а значення - бажаними функціями агрегування.
# Different aggregations for different values
dict_agg_pivot = pd.pivot_table(df,
index='Region',
values=['Revenue', 'Units_Sold'],
aggfunc={
'Revenue': 'sum',
'Units_Sold': 'mean'
},
fill_value=0)
print(dict_agg_pivot)
Вивід:
Revenue Units_Sold
Region
Asia 13108 17.833333
Europe 16575 8.166667
North America 29858 14.333333
Цей рівень контролю робить pivot_table() основним інструментом для складного аналізу даних.
Обчислення загальних підсумків за допомогою margins
Для цілей звітності часто важливо мати підсумки рядків і стовпців. Аргумент margins=True надає це без додаткових зусиль.
# Adding totals with margins=True
revenue_with_margins = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
columns='Region',
aggfunc='sum',
fill_value=0,
margins=True,
margins_name='Grand Total') # Custom name for totals
print(revenue_with_margins)
Вивід:
Region Asia Europe North America Grand Total Product_Category Apparel 1125 625 0 1750 Books 336 360 488 1184 Electronics 13200 14550 29100 56850 Grand Total 14661 15535 29588 59784
Pandas автоматично обчислює суму для кожного рядка (загальний дохід на категорію продукту в усіх регіонах) і кожного стовпця (загальний дохід на регіон у всіх категоріях), а також загальний підсумок для всіх даних у нижньому правому куті.
Практичний приклад використання: аналіз на основі часу
Зведені таблиці не обмежуються статичними категоріями. Вони неймовірно корисні для аналізу даних часових рядів. Давайте знайдемо загальний дохід за кожен місяць.
Спочатку нам потрібно витягти місяць зі стовпця "Дата". Ми можемо використовувати аксесор .dt у Pandas для цього.
# Extract month from the Date column
df['Month'] = df['Date'].dt.month_name()
# Pivot to see monthly revenue by product category
monthly_revenue = pd.pivot_table(df,
values='Revenue',
index='Month',
columns='Product_Category',
aggfunc='sum',
fill_value=0)
# Optional: Order the months correctly
month_order = ['January', 'February', 'March']
monthly_revenue = monthly_revenue.reindex(month_order)
print(monthly_revenue)
Вивід:
Product_Category Apparel Books Electronics Month January 250 360 23100 February 795 794 24250 March 705 30 9500
Ця таблиця дає нам чітке уявлення про ефективність продажів кожної категорії з часом, що дозволяє нам легко визначати тенденції, сезонність або аномалії.
pivot_table() vs. groupby(): У чому різниця?
Це поширене питання для тих, хто вивчає Pandas. Дві функції тісно пов'язані, і фактично pivot_table() побудовано на основі groupby().
groupby()є більш загальною та фундаментальною операцією. Вона групує дані на основі деяких критеріїв, а потім дозволяє застосувати функцію агрегування. Результатом зазвичай є Pandas Series або DataFrame з ієрархічним індексом, але він залишається у "довгому" форматі.pivot_table()- це спеціалізований інструмент, який виконує групування, а потім змінює форму даних. Її основна мета - перетворити дані з довгого формату на широкий формат, який часто легше читається.
Давайте переглянемо наш перший приклад за допомогою groupby():
# Same result as our first pivot table, but using groupby
category_revenue_groupby = df.groupby('Product_Category')['Revenue'].sum()
print(category_revenue_groupby)
Результатом є Pandas Series, який функціонально еквівалентний DataFrame з нашої першої зведеної таблиці. Однак, коли ви вводите другий ключ групування (наприклад, "Регіон"), різниця стає очевидною.
# Grouping by two columns
groupby_multi = df.groupby(['Product_Category', 'Region'])['Revenue'].sum()
print(groupby_multi)
Вивід (Series з MultiIndex):
Product_Category Region
Apparel Asia 1125
Europe 625
Books Asia 336
Europe 360
North America 488
Electronics Asia 13200
Europe 14550
North America 29100
Name: Revenue, dtype: int64
Щоб отримати той самий "широкий" формат, що й pivot_table(index='Product_Category', columns='Region'), вам потрібно використовувати groupby() з подальшим unstack():
# Replicating a pivot table with groupby().unstack()
groupby_unstack = df.groupby(['Product_Category', 'Region'])['Revenue'].sum().unstack(fill_value=0)
print(groupby_unstack)
Це дає точно такий самий вивід, як і наша зведена таблиця зі стовпцями. Отже, ви можете розглядати pivot_table() як зручний ярлик для звичайного робочого процесу groupby().aggregate().unstack().
Коли що використовувати?
- Використовуйте
pivot_table(), коли вам потрібен зручний для читання, широкий вивід, особливо для звітності або створення перехресних таблиць. - Використовуйте
groupby(), коли вам потрібна більша гнучкість, ви виконуєте проміжні обчислення в конвеєрі обробки даних або коли змінений широкий формат не є вашою кінцевою метою.
Продуктивність і найкращі практики
Хоча pivot_table() є потужним інструментом, важливо використовувати його ефективно, особливо з великими наборами даних.
- Спочатку фільтруйте, потім зводьте: Якщо вам потрібно проаналізувати лише підмножину ваших даних (наприклад, продажі за останній рік), відфільтруйте DataFrame перед застосуванням зведеної таблиці. Це зменшує обсяг даних, які функція має обробити.
- Використовуйте категоріальні типи: Для стовпців, які ви часто використовуєте як індекси або стовпці у своїх зведених таблицях (наприклад, "Регіон" або "Категорія_продукту"), перетворіть їх на тип даних "category" у Pandas. Це може значно зменшити використання пам'яті та пришвидшити операції групування.
df['Region'] = df['Region'].astype('category') - Зберігайте читабельність: Уникайте створення зведених таблиць із занадто великою кількістю індексів і стовпців. Хоча це можливо, зведена таблиця, яка має сотні стовпців завширшки та тисячі рядків завдовжки, може стати такою ж нечитабельною, як і вихідні необроблені дані. Використовуйте її для створення цільових підсумків.
- Розумійте агрегування: Пам'ятайте про свій вибір
aggfunc. Використання "sum" для цін не має сенсу, тоді як "mean" може бути більш доречним. Завжди переконуйтеся, що ваше агрегування відповідає питанню, на яке ви намагаєтесь відповісти.
Висновок: Ваш інструмент для інформативних підсумків
Функція Pandas pivot_table() є незамінним інструментом в арсеналі будь-якого аналітика даних. Вона надає декларативний, виразний і потужний спосіб переходу від безладних, детальних даних до чистих, інформативних підсумків. Розуміючи та опановуючи її основні компоненти - values, index, columns і aggfunc - і використовуючи її розширені функції, такі як багаторівневе індексування, спеціальні агрегації та поля, ви можете змінювати форму своїх даних, щоб відповідати на складні бізнес-питання лише кількома рядками коду Python.
Наступного разу, коли ви зіткнетеся з великим набором даних, не піддавайтеся бажанню прокручувати нескінченні рядки. Натомість подумайте про питання, на які вам потрібно відповісти, і про те, як зведена таблиця може змінити форму ваших даних, щоб розкрити приховані в них історії. Щасливого зведення!