Ovládněte přetváření dat s kontingenčními tabulkami v Python Pandas. Hloubkový pohled na syntaxi, pokročilé techniky a praktické příklady pro globální analýzu dat.
Kontingenční tabulky v Python Pandas: Komplexní průvodce přetvářením dat
Ve světě datové analýzy není schopnost sumarizovat, agregovat a restrukturovat data jen dovedností – je to superschopnost. Surová data ve své přirozené formě často připomínají rozsáhlou, detailní účetní knihu. Jsou bohatá na informace, ale obtížně se interpretují. Abychom z nich získali smysluplné poznatky, musíme tuto knihu přeměnit na stručný souhrn. Přesně v tom vynikají kontingenční tabulky a pro programátory v Pythonu poskytuje knihovna Pandas výkonný a flexibilní nástroj: pivot_table().
Tento průvodce je určen pro globální publikum datových analytiků, vědců a nadšenců do Pythonu. Ponoříme se hluboko do mechaniky kontingenčních tabulek v Pandas, od základních konceptů až po pokročilé techniky. Ať už sumarizujete prodejní údaje z různých kontinentů, analyzujete klimatická data napříč regiony nebo sledujete metriky projektu pro distribuovaný tým, zvládnutí kontingenčních tabulek zásadně změní váš přístup k prozkoumávání dat.
Co přesně je kontingenční tabulka?
Pokud jste někdy používali tabulkový software jako Microsoft Excel nebo Google Sheets, pravděpodobně jste se s konceptem kontingenční tabulky již setkali. Je to interaktivní tabulka, která vám umožňuje reorganizovat a sumarizovat vybrané sloupce a řádky dat z větší datové sady za účelem získání požadovaného reportu.
Kontingenční tabulka dělá dvě klíčové věci:
- Agregace: Vypočítá souhrnnou statistiku (jako je součet, průměr nebo počet) pro číselná data seskupená podle jedné nebo více kategorií.
- Přetváření: Transformuje data z 'dlouhého' formátu na 'široký' formát. Místo toho, aby byly všechny hodnoty v jednom sloupci, 'překlopí' (pivotuje) jedinečné hodnoty ze sloupce do nových sloupců ve výstupu.
Funkce pivot_table() v knihovně Pandas přináší tuto mocnou funkcionalitu přímo do vašeho pracovního postupu analýzy dat v Pythonu, což umožňuje reprodukovatelné, skriptovatelné a škálovatelné přetváření dat.
Nastavení prostředí a vzorová data
Než začneme, ujistěte se, že máte nainstalovanou knihovnu Pandas. Pokud ne, můžete ji nainstalovat pomocí pip, správce balíčků Pythonu:
pip install pandas
Nyní si ji importujme do našeho Python skriptu nebo notebooku:
import pandas as pd
import numpy as np
Vytvoření globální datové sady prodejů
Aby byly naše příklady praktické a globálně relevantní, vytvoříme si syntetickou datovou sadu reprezentující prodejní data nadnárodní e-commerce společnosti. Tato datová sada bude obsahovat informace o prodejích z různých regionů, zemí a kategorií produktů.
# 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())
Tato datová sada nám dává solidní základ se směsí kategorických dat (Region, Country, Product_Category), číselných dat (Units_Sold, Revenue) a časových řad (Date).
Anatomie funkce pivot_table()
Funkce pivot_table() v Pandas je neuvěřitelně všestranná. Pojďme si rozebrat její nejdůležitější parametry:
pandas.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, margins_name='All')
- data: DataFrame, který chcete kontingovat.
- values: Sloupec (sloupce), který obsahuje data k agregaci. Pokud není specifikován, budou použity všechny zbývající číselné sloupce.
- index: Sloupec (sloupce), jehož jedinečné hodnoty budou tvořit řádky nové kontingenční tabulky. Někdy se nazývá 'klíč seskupení'.
- columns: Sloupec (sloupce), jehož jedinečné hodnoty budou 'překlopeny' a vytvoří sloupce nové tabulky.
- aggfunc: Agregační funkce, která se použije na 'values'. Může to být řetězec jako 'sum', 'mean', 'count', 'min', 'max', nebo funkce jako
np.sum. Můžete také předat seznam funkcí nebo slovník pro použití různých funkcí na různé sloupce. Výchozí hodnota je 'mean'. - fill_value: Hodnota, která nahradí jakékoli chybějící výsledky (NaN) v kontingenční tabulce.
- margins: Booleovská hodnota. Pokud je nastavena na
True, přidá mezisoučty pro řádky a sloupce (také známé jako celkový součet). - margins_name: Název pro řádek/sloupec, který obsahuje součty, když
margins=True. Výchozí hodnota je 'All'.
Vaše první kontingenční tabulka: Jednoduchý příklad
Začněme s běžnou obchodní otázkou: "Jaký je celkový příjem generovaný každou kategorií produktů?"
Abychom na to odpověděli, musíme:
- Použít
Product_Categorypro řádky (index). - Agregovat sloupec
Revenue(values). - Použít součet jako naši agregační funkci (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)
Výstup:
Revenue
Product_Category
Apparel 1645
Books 1184
Electronics 56850
Okamžitě máme jasný a stručný souhrn. Surový transakční záznam o 20 řádcích byl přetvořen na tabulku o 3 řádcích, která přímo odpovídá na naši otázku. To je základní síla kontingenční tabulky.
Přidání dimenze sloupců
Nyní to rozšíříme. Co když chceme vidět celkové příjmy podle kategorie produktů, ale také rozdělené podle regionu? Zde přichází na řadu parametr 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)
Výstup:
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
Tento výstup je mnohem bohatší. Překlopili jsme jedinečné hodnoty ze sloupce 'Region' ('Asia', 'Europe', 'North America') do nových sloupců. Nyní můžeme snadno porovnávat, jak si různé kategorie produktů vedou v jednotlivých regionech. Vidíme také hodnotu NaN (Not a Number). To znamená, že v naší datové sadě nebyly zaznamenány žádné prodeje v kategorii 'Apparel' pro region 'North America'. To je samo o sobě cenná informace!
Pokročilé techniky kontingence
Základy jsou mocné, ale skutečná flexibilita pivot_table() se odhaluje v jejích pokročilých funkcích.
Zpracování chybějících hodnot pomocí fill_value
Hodnota NaN v naší předchozí tabulce je přesná, ale pro reporting nebo další výpočty může být vhodnější ji zobrazit jako nulu. Parametr fill_value to usnadňuje.
# 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)
Výstup:
Region Asia Europe North America Product_Category Apparel 1125 625 0 Books 336 360 488 Electronics 13200 14550 29100
Tabulka je nyní čistší a snáze čitelná, zejména pro netechnické publikum.
Práce s více indexy (hierarchické indexování)
Co když potřebujete seskupovat podle více než jedné kategorie v řádcích? Například, rozdělme prodeje podle Region a poté podle Country v rámci každého regionu. Můžeme předat seznam sloupců parametru 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)
Výstup:
Revenue
Region Country
Asia China 488
India 1760
Japan 10860
Europe France 1020
Germany 14440
UK 1115
North America Canada 17800
USA 12058
Pandas automaticky vytvořil MultiIndex na řádcích. Tato hierarchická struktura je fantastická pro podrobnější analýzu vašich dat a sledování vnořených vztahů. Stejnou logiku můžete použít i pro parametr columns k vytvoření hierarchických sloupců.
Použití více agregačních funkcí
Někdy jedna souhrnná statistika nestačí. Možná budete chtít vidět jak celkové příjmy (součet), tak průměrnou velikost transakce (průměr) pro každou skupinu. Můžete předat seznam funkcí do aggfunc.
# Using multiple aggregation functions
multi_agg_pivot = pd.pivot_table(df,
values='Revenue',
index='Region',
aggfunc=['sum', 'mean', 'count'])
print(multi_agg_pivot)
Výstup:
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
Tento jediný příkaz nám dává komplexní souhrn: celkové příjmy, průměrné příjmy na transakci a počet transakcí pro každý region. Všimněte si, jak Pandas vytváří hierarchické sloupce, aby udržel výstup organizovaný.
Aplikace různých funkcí na různé hodnoty
Můžete být ještě podrobnější. Představte si, že chcete vidět součet Revenue, ale průměr Units_Sold. Můžete předat slovník do aggfunc, kde klíče jsou názvy sloupců ('values') a hodnoty jsou požadované agregační funkce.
# 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)
Výstup:
Revenue Units_Sold
Region
Asia 13108 17.833333
Europe 16575 8.166667
North America 29858 14.333333
Tato úroveň kontroly je to, co dělá z pivot_table() prvotřídní nástroj pro sofistikovanou analýzu dat.
Výpočet celkových součtů pomocí margins
Pro účely reportingu jsou často nezbytné součty řádků a sloupců. Argument margins=True to poskytuje s nulovým dodatečným úsilím.
# 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)
Výstup:
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 automaticky vypočítá součet pro každý řádek (celkové příjmy na kategorii produktu napříč všemi regiony) a každý sloupec (celkové příjmy na region napříč všemi kategoriemi), plus celkový součet pro všechna data v pravém dolním rohu.
Praktický příklad: Analýza na základě času
Kontingenční tabulky se neomezují pouze na statické kategorie. Jsou neuvěřitelně užitečné pro analýzu časových řad. Najděme celkové příjmy za každý měsíc.
Nejprve musíme extrahovat měsíc z našeho sloupce 'Date'. K tomu můžeme v Pandas použít akcesor .dt.
# 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)
Výstup:
Product_Category Apparel Books Electronics Month January 250 360 23100 February 795 794 24250 March 705 30 9500
Tato tabulka nám poskytuje jasný přehled o prodejní výkonnosti každé kategorie v čase, což nám umožňuje snadno odhalit trendy, sezónnost nebo anomálie.
pivot_table() vs. groupby(): Jaký je rozdíl?
Toto je častá otázka pro ty, kteří se učí Pandas. Obě funkce jsou úzce spjaty a ve skutečnosti je pivot_table() postavena na groupby().
groupby()je obecnější a základnější operace. Seskupuje data na základě nějakého kritéria a poté vám umožní aplikovat agregační funkci. Výsledkem je typicky Pandas Series nebo DataFrame s hierarchickým indexem, ale zůstává v 'dlouhém' formátu.pivot_table()je specializovaný nástroj, který provádí seskupení a poté data přetváří. Jeho primárním účelem je transformovat data z dlouhého formátu na široký formát, který je často lépe čitelný pro člověka.
Vraťme se k našemu prvnímu příkladu s použitím groupby():
# Same result as our first pivot table, but using groupby
category_revenue_groupby = df.groupby('Product_Category')['Revenue'].sum()
print(category_revenue_groupby)
Výsledkem je Pandas Series, která je funkčně ekvivalentní DataFrame z naší první kontingenční tabulky. Když však zavedete druhý klíč pro seskupení (jako 'Region'), rozdíl se stane zřejmým.
# Grouping by two columns
groupby_multi = df.groupby(['Product_Category', 'Region'])['Revenue'].sum()
print(groupby_multi)
Výstup (Series s MultiIndexem):
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
Abyste získali stejný 'široký' formát jako pivot_table(index='Product_Category', columns='Region'), museli byste použít groupby() následované unstack():
# Replicating a pivot table with groupby().unstack()
groupby_unstack = df.groupby(['Product_Category', 'Region'])['Revenue'].sum().unstack(fill_value=0)
print(groupby_unstack)
Toto produkuje přesně stejný výstup jako naše kontingenční tabulka se sloupci. Můžete tedy považovat pivot_table() za pohodlnou zkratku pro běžný pracovní postup groupby().aggregate().unstack().
Kdy kterou použít?
- Použijte
pivot_table(), když chcete pro člověka čitelný výstup v širokém formátu, zejména pro reporting nebo vytváření křížových tabulek (crosstabs). - Použijte
groupby(), když potřebujete větší flexibilitu, provádíte mezivýpočty v potrubí pro zpracování dat, nebo když přetvořený široký formát není vaším konečným cílem.
Výkon a osvědčené postupy
I když je pivot_table() výkonná, je důležité ji používat efektivně, zejména s velkými datovými sadami.
- Nejprve filtrovat, potom kontingovat: Pokud potřebujete analyzovat pouze podmnožinu dat (např. prodeje za poslední rok), filtrujte DataFrame před aplikací kontingenční tabulky. Tím se sníží množství dat, které musí funkce zpracovat.
- Používejte kategorické typy: Pro sloupce, které často používáte jako indexy nebo sloupce ve vašich kontingenčních tabulkách (jako 'Region' nebo 'Product_Category'), převeďte je v Pandas na datový typ 'category'. To může výrazně snížit využití paměti a zrychlit operace seskupování.
df['Region'] = df['Region'].astype('category') - Udržujte čitelnost: Vyhněte se vytváření kontingenčních tabulek s příliš mnoha indexy a sloupci. I když je to možné, kontingenční tabulka, která je stovky sloupců široká a tisíce řádků dlouhá, se může stát stejně nečitelnou jako původní surová data. Používejte ji k vytváření cílených souhrnů.
- Rozumějte agregaci: Dávejte pozor na volbu
aggfunc. Použití 'sum' na ceny nemá smysl, zatímco 'mean' může být vhodnější. Vždy se ujistěte, že vaše agregace odpovídá otázce, na kterou se snažíte odpovědět.
Závěr: Váš nástroj pro přehledné souhrny
Funkce pivot_table() v Pandas je nepostradatelným nástrojem v sadě nástrojů každého datového analytika. Poskytuje deklarativní, expresivní a výkonný způsob, jak přejít od neuspořádaných, detailních dat k čistým a přehledným souhrnům. Porozuměním a zvládnutím jejích klíčových komponent – values, index, columns a aggfunc – a využitím jejích pokročilých funkcí, jako je víceúrovňové indexování, vlastní agregace a mezisoučty, můžete přetvářet svá data tak, abyste odpověděli na složité obchodní otázky jen s několika řádky kódu v Pythonu.
Až se příště setkáte s velkou datovou sadou, odolejte nutkání procházet nekonečné řádky. Místo toho se zamyslete nad otázkami, na které potřebujete odpovědět, a jak může kontingenční tabulka přetvořit vaše data, aby odhalila příběhy, které se v nich skrývají. Šťastné kontingování!