Овладейте преоформянето на данни с Pivot таблици в Python Pandas. Дълбоко потапяне в синтаксиса, техниките и практически примери.
Pivot таблици в Python Pandas: Изчерпателно ръководство за преоформяне на данни
В света на анализа на данни, способността да се обобщават, агрегират и преструктурират данни не е просто умение – това е суперсила. Суровите данни, в тяхната оригинална форма, често приличат на разтегнат, подробен регистър. Той е богат на информация, но труден за интерпретация. За да извлечем смислени прозрения, трябва да преобразуваме този регистър в кратко обобщение. Именно тук се отличават pivot таблиците, а за Python програмистите библиотеката Pandas предоставя мощен и гъвкав инструмент: pivot_table().
Това ръководство е предназначено за глобална аудитория от анализатори на данни, учени и ентусиасти на Python. Ще се потопим дълбоко в механиката на pivot таблиците в Pandas, преминавайки от основните концепции към усъвършенствани техники. Независимо дали обобщавате цифри за продажби от различни континенти, анализирате климатични данни в различни региони или проследявате показатели за проекти за разпределен екип, овладяването на pivot таблиците ще промени фундаментално начина, по който подхождате към проучването на данни.
Какво точно представлява Pivot таблица?
Ако някога сте използвали софтуер за електронни таблици като Microsoft Excel или Google Sheets, вероятно сте запознати с концепцията за pivot таблица. Това е интерактивна таблица, която ви позволява да реорганизирате и обобщавате избрани колони и редове от данни от по-голям набор от данни, за да получите желания отчет.
Pivot таблицата върши две основни неща:
- Агрегация: Изчислява обобщаваща статистика (като сума, средна стойност или брой) за числени данни, групирани по една или повече категории.
- Преоформяне: Преобразува данни от „дълъг“ формат в „широк“ формат. Вместо да има всички стойности в една колона, тя „преоформя“ уникалните стойности от колона в нови колони в изхода.
Функцията pivot_table() на Pandas внася тази мощна функционалност директно във вашия работен процес за анализ на данни с Python, позволявайки възпроизводимо, скриптово и мащабируемо преоформяне на данни.
Настройване на вашата среда и примерни данни
Преди да започнем, уверете се, че имате инсталирана библиотеката Pandas. Ако не, можете да я инсталирате с помощта на pip, инсталатора на пакети на Python:
pip install pandas
Сега, нека я импортираме в нашия Python скрипт или notebook:
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())
Този набор от данни ни дава солидна основа със смес от категорийни данни (Region, Country, Product_Category), числени данни (Units_Sold, Revenue) и времеви редове (Date).
Анатомията на pivot_table()
Функцията pivot_table() на Pandas е невероятно гъвкава. Нека разгледаме най-важните й параметри:
pandas.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, margins_name='All')
- data: DataFrame, който искате да преоформите.
- values: Колона(и), съдържаща данните за агрегиране. Ако не е посочено, ще се използват всички останали числени колони.
- index: Колона(и), чиито уникални стойности ще образуват редовете на новата pivot таблица. Това понякога се нарича „групиращ ключ“.
- columns: Колона(и), чиито уникални стойности ще бъдат „преоформени“, за да образуват колоните на новата таблица.
- aggfunc: Функцията за агрегиране, която да се приложи към „values“. Това може да бъде низ като „sum“, „mean“, „count“, „min“, „max“ или функция като
np.sum. Можете също да предадете списък от функции или речник, за да приложите различни функции към различни колони. По подразбиране е „mean“. - fill_value: Стойност, която да замести всички липсващи резултати (NaN) в pivot таблицата.
- margins: Булева стойност. Ако е зададено на
True, добавя междинни суми за редове и колони (известни също като общ сбор). - margins_name: Името за реда/колоната, която съдържа общосумите, когато
margins=True. По подразбиране е „All“.
Вашата първа Pivot таблица: Прост пример
Нека започнем с често срещан бизнес въпрос: „Каква е общата приходи, генерирани от всяка продуктова категория?“
За да отговорим на това, трябва да:
- Използваме
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 реда, която директно отговаря на нашия въпрос. Това е фундаменталната сила на pivot таблицата.
Добавяне на колонен размер
Сега, нека разширим това. Какво ще стане, ако искаме да видим общите приходи по продуктова категория, но също така разделени по регион? Тук влиза в действие параметърът 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
Този изход е много по-богат. Преоформихме уникалните стойности от колоната „Region“ („Asia“, „Europe“, „North America“) в нови колони. Сега можем лесно да сравним как различните продуктови категории се представят в различните региони. Виждаме и стойност NaN (Not a Number). Това показва, че не са регистрирани продажби на „Apparel“ за „North America“ в нашия набор от данни. Това е ценна информация сама по себе си!
Усъвършенствани техники за Pivot
Основите са мощни, но истинската гъвкавост на 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 автоматично изчислява сумата за всеки ред (общите приходи за продуктова категория във всички региони) и всеки стълб (общите приходи за регион във всички категории), плюс обща сума за всички данни в долния десен ъгъл.
Практичен случай на употреба: Анализ, базиран на времето
Pivot таблиците не се ограничават до статични категории. Те са невероятно полезни за анализиране на данни от времеви редове. Нека намерим общите приходи за всеки месец.
Първо, трябва да извлечем месеца от нашата колона „Date“. Можем да използваме аксесора .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() срещу 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 от нашата първа pivot таблица. Въпреки това, когато въведете втори ключ за групиране (като „Region“), разликата става ясна.
# 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 таблица с колони. Така че можете да мислите за pivot_table() като удобен пряк път за общия работен процес groupby().aggregate().unstack().
Кога да използвате кое?
- Използвайте
pivot_table(), когато искате четлив, широк формат на изхода, особено за отчитане или създаване на кръстосани таблици. - Използвайте
groupby(), когато се нуждаете от повече гъвкавост, извършвате междинни изчисления в тръбопровод за обработка на данни или когато преоформеният, широк формат не е крайната ви цел.
Производителност и най-добри практики
Докато pivot_table() е мощен, важно е да го използвате ефективно, особено с големи набори от данни.
- Филтрирайте първо, Pivot по-късно: Ако трябва само да анализирате подмножество от вашите данни (напр. продажби от последната година), филтрирайте DataFrame преди да приложите pivot таблицата. Това намалява обема данни, които функцията трябва да обработи.
- Използвайте категорийни типове: За колони, които използвате често като индекси или колони във вашите pivot таблици (като „Region“ или „Product_Category“), ги преобразувайте в „category“ dtype в Pandas. Това може значително да намали използването на паметта и да ускори операциите по групиране.
df['Region'] = df['Region'].astype('category') - Поддържайте го четливо: Избягвайте създаването на pivot таблици с твърде много индекси и колони. Въпреки че е възможно, pivot таблица, която е стотици колони широка и хиляди редове дълга, може да стане също толкова нечетима, колкото оригиналните сурови данни. Използвайте го, за да създадете целеви обобщения.
- Разберете агрегацията: Бъдете внимателни при избора на ваш
aggfunc. Използването на „sum“ за цените няма смисъл, докато „mean“ може да е по-подходящо. Винаги се уверявайте, че вашата агрегация е в съответствие с въпроса, на който се опитвате да отговорите.
Заключение: Вашият инструмент за проницателни обобщения
Функцията pivot_table() на Pandas е незаменим инструмент в набора от инструменти на всеки анализатор на данни. Тя предоставя декларативен, изразителен и мощен начин да преминете от разхвърляни, подробни данни към чисти, проницателни обобщения. Чрез разбиране и овладяване на нейните основни компоненти — values, index, columns и aggfunc — и използване на нейните усъвършенствани функции като многостепенно индексиране, персонализирани агрегации и маржини, можете да преоформите вашите данни, за да отговорите на сложни бизнес въпроси само с няколко реда код на Python.
Следващия път, когато сте изправени пред голям набор от данни, устоявайте на желанието да превъртате през безкрайни редове. Вместо това, помислете за въпросите, на които трябва да отговорите, и как pivot таблицата може да преоформи вашите данни, за да разкрие историите, скрити вътре. Приятно преоформяне!