|
| 1 | +## Další funkce pro tvorbu pivot tabulek |
| 2 | + |
| 3 | +Pivot tabulky velmi často provádíme v kombinaci s nějakou agregací. Uvažujme například, že by nás zajímal průměrný obsah výživných látek za jednotlivé kategorie, nikoli za konkrétní potraviny. |
| 4 | + |
| 5 | +```py |
| 6 | +import pandas as pd |
| 7 | + |
| 8 | +food_nutrient = pd.read_csv("food_nutrient.csv") |
| 9 | +branded_food = pd.read_csv("branded_food.csv") |
| 10 | +food = pd.concat([pd.read_csv("food_sample_100.csv"), pd.read_csv("food_other.csv")], ignore_index=True) |
| 11 | +food_merged = pd.merge(food, food_nutrient, on="fdc_id") |
| 12 | +food_merged = pd.merge(food_merged, branded_food, on="fdc_id") |
| 13 | +``` |
| 14 | + |
| 15 | +Protože v datech máme obrovské množství různých kategorií i výživných látek, u dat provedeme filtrování. Výběr kategorií s největším počtem potravin jsme již provedli v lekci o vizualizacích. Nyní provedeme výběr výživných látek. Pro naši kontingenční tabulku si vybereme tyto výživné látky: |
| 16 | + |
| 17 | +- `Protein` (bílkoviny), |
| 18 | +- `Sodium, Na` (sodík, Na), |
| 19 | +- `Total lipid (fat)` (lipidy (tuky)), |
| 20 | +- `Carbohydrate, by difference` (sacharidy, měřené rozdílově), |
| 21 | +- `Sugars, total including NLEA` (cukry, celkem včetně NLEA), |
| 22 | +- `Fatty acids, total saturated` (nasycené mastné kyseliny, celkem), |
| 23 | +- `Cholesterol` (cholesterol), |
| 24 | +- `Fiber, total dietary` (vláknina, celková stravová), |
| 25 | +- `Calcium, Ca` (vápník, Ca), |
| 26 | +- `Iron, Fe` (železo, Fe). |
| 27 | + |
| 28 | +Nejprve si vyzkoušíme funkci `pivot_table()`. Pozor, jedná se o odlišnou funkci, než kterou jsme využívali v předchozí lekci. Funkci `pivot_table` určíme pět parametrů, tj. o jeden parametr víc, než který jsme zadávali funkci `pivot()`. |
| 29 | + |
| 30 | +- Prvním parametrem (`data`) určujeme tabulku, se kterou bude funkce pracovat. |
| 31 | +- Druhý parametr (`value`) obsahuje název sloupce, ze kterého budou čteny hodnoty, které budou "ve vnitřní části" tabulky. V tomto případě již může být pro každou kombinaci název řádku a názvu sloupce více hodnot, protože funkce počítá s provedením agregace. |
| 32 | +- Třetí parametr (`index`) slouží jako popisek řádků. V našem případě zvolíme sloupeček `"branded_food_category"`, tj. název kategorie. |
| 33 | +- Čtvrtý parametr (`columns`) bude použit k vytvoření nových sloupečků. Sem doplníme sloupec `name`. |
| 34 | +- Jako pátý parametr (`aggfunc`) je třeba vložit funkce, která bude použita k agregaci hodnot. Protože předpokládáme, že pro každou kombinaci kategorie a výživné látky budeme znát více hodnot (protože v každé kategorii máme spousty potravin), je třeba použít nějakou funkci, která z těchto hodnot vypočte jedno číslo. Jedná se obdobu agregace, na což odkazuje i název parametru. Pokud bychom chtěli spočítat průměrnou hodnotu, můžeme například použít funkci `mean()` z modulu `numpy`. Pozor na to, že píšeme pouze název funkce **bez závorek**. Neprovádíme totiž volání funkce, to dělá funkce `pivot_table` za nás. |
| 35 | + |
| 36 | +Na rozdíl od funkce `pivot()` nemusíme parametry psát jako pojmenované. |
| 37 | + |
| 38 | +```py |
| 39 | +import numpy as np |
| 40 | + |
| 41 | +pd.pivot_table(food_merged, "amount", "branded_food_category", "name", np.mean) |
| 42 | +``` |
| 43 | + |
| 44 | +Z výsledné tabulky vidíme, jak se liší průměrné množství výživných látek v jednotlivých potravinách. Kupříkladu sýry jsou poměrně bohaté na vápaník a cholesterol, naopak je v nich poměrně málo vlákniny. |
| 45 | + |
| 46 | +Alternativou k funkci `pivot_table()` je funkce `crosstab()`. Ta se liší od funkce `pivot_table()` především v tom, že jí zadáváme data jako série hodnot, nikoli jako tabulku a následně názvy sloupců. |
| 47 | + |
| 48 | +```py |
| 49 | +pd.crosstab(food_merged["branded_food_category"], food_merged["name"], food_merged["amount"], aggfunc=np.mean) |
| 50 | +``` |
| 51 | + |
| 52 | +### Standardizace a teplotní mapa |
| 53 | + |
| 54 | +Kontingenční tabulka je časově náročná na čtení, především v případě, že má poměrně hodně řádků nebo sloupců. Pro rychlý přehled může být užitečnější typ vizualizace označovaný jako :term{cs="teplotní mapa" en="heat map"}. Ten převede hodnotu na barevnou škálu. V teplotní mapě můžeme rychle nalézt především výrazně nadprůměrné či podprůměrné hodnoty. U našich dat ale může být problém v tom, že máme v různých sloupcích řádově odlišné hodnoty. Je to samozřejmě ovlivněno tím, že některé výživné látky jsou zobrazné v odlišných jednotkách (množství látky v gramech a miligramech na 100 gramů potraviny). Problém bychom nevyřešili ani převodem na stejné jednotky. Vápníku nebo sodíku totiž bude v potravinách většinou řádově méně než proteinů nebo cukrů. |
| 55 | + |
| 56 | +Problém ale můžeme vyřešit pomocí procesu označovaného jako {cs="normalizace" en="normalization"}. Normalizace dat v kontextu statistiky a zpracování dat znamená převedení různých rozsahů hodnot na společnou škálu, čímž se usnadňuje jejich srovnání a analýza. Tento proces pomáhá odstranit zkreslení v datech způsobená různými měřítky a umožňuje lépe identifikovat vzory a vztahy mezi proměnnými. Normalizace je klíčová pro efektivní algoritmické zpracování, například {cs="strojovém učení" en="machine learning"} a datové analýze. |
| 57 | + |
| 58 | +Prakticky normalizace obsahuje dva kroky: |
| 59 | + |
| 60 | +- Od hodnot odečteme průměr. Tím pádem se normalizované hodnoty budou pohybovat kolem nuly. Pokud bude nějaká normalizovaná hodnota záporná, v původních datech byla podprůměrná. Pokud bude normalizovaná hodnota kladná, v původních datech byla nadprůměrná. |
| 61 | +- Vydělíme data jejich variabilitou, konkrétně směrodatnou odchylkou. Tím data převedeme na stejné jednotky. Data se budou pohybovat ve stejných jednotkách, ať už byla původní data v desetinných čísel nebo v minionech. |
| 62 | + |
| 63 | +Nejprve tedy provedeme normalizaci dat. |
| 64 | + |
| 65 | +```py |
| 66 | +food_pivot_norm = (food_pivot - food_pivot.mean()) / food_pivot.std() |
| 67 | +``` |
| 68 | + |
| 69 | +A ve druhém kroku vytvoříme teplotní mapu. |
| 70 | + |
| 71 | +```py |
| 72 | +import seaborn as sns |
| 73 | +ax = sns.heatmap(food_pivot_norm) |
| 74 | +ax.set(xlabel="Výživná látka", ylabel="Kategorie", title="Množství průměrných látek dle kategorií") |
| 75 | +``` |
| 76 | + |
| 77 | +Pro lepší čitelnost můžeme změnit výchozí barevnou škálu pomocí parametru `cmap`. Můžeme použít například škálu `"Blues"`, která je postavená na sytosti modré barvy. |
0 commit comments