-
Notifications
You must be signed in to change notification settings - Fork 6
Upravy 2 #87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Upravy 2 #87
Changes from 4 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
9abe06b
Úpravy
pesikj 4fc18cb
Část o pivot tabulkách
pesikj 96e392b
Úpravy
pesikj ff545f7
Fix
pesikj 621cc3d
Update python-pro-data-1/podmineny-vyber/excs/dve-kriteria.md
pesikj 11c388c
Update python-pro-data-1/pivot-tabulky/excs/dve-kriteria.md
pesikj File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,4 @@ lessons: | |
- spojovani | ||
- agregace | ||
- vizualizace | ||
- pivot-tabulky |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
## Další funkce pro tvorbu pivot tabulek | ||
|
||
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. | ||
|
||
```py | ||
import pandas as pd | ||
|
||
food_nutrient = pd.read_csv("food_nutrient.csv") | ||
branded_food = pd.read_csv("branded_food.csv") | ||
food = pd.concat([pd.read_csv("food_sample_100.csv"), pd.read_csv("food_other.csv")], ignore_index=True) | ||
food_merged = pd.merge(food, food_nutrient, on="fdc_id") | ||
food_merged = pd.merge(food_merged, branded_food, on="fdc_id") | ||
``` | ||
|
||
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: | ||
|
||
- `Protein` (bílkoviny), | ||
- `Sodium, Na` (sodík, Na), | ||
- `Total lipid (fat)` (lipidy (tuky)), | ||
- `Carbohydrate, by difference` (sacharidy, měřené rozdílově), | ||
- `Sugars, total including NLEA` (cukry, celkem včetně NLEA), | ||
- `Fatty acids, total saturated` (nasycené mastné kyseliny, celkem), | ||
- `Cholesterol` (cholesterol), | ||
- `Fiber, total dietary` (vláknina, celková stravová), | ||
- `Calcium, Ca` (vápník, Ca), | ||
- `Iron, Fe` (železo, Fe). | ||
|
||
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()`. | ||
|
||
- Prvním parametrem (`data`) určujeme tabulku, se kterou bude funkce pracovat. | ||
- 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. | ||
- Třetí parametr (`index`) slouží jako popisek řádků. V našem případě zvolíme sloupeček `"branded_food_category"`, tj. název kategorie. | ||
- Čtvrtý parametr (`columns`) bude použit k vytvoření nových sloupečků. Sem doplníme sloupec `name`. | ||
- 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. | ||
|
||
Na rozdíl od funkce `pivot()` nemusíme parametry psát jako pojmenované. | ||
|
||
```py | ||
import numpy as np | ||
|
||
pd.pivot_table(food_merged, "amount", "branded_food_category", "name", np.mean) | ||
``` | ||
|
||
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. | ||
|
||
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ů. | ||
|
||
```py | ||
pd.crosstab(food_merged["branded_food_category"], food_merged["name"], food_merged["amount"], aggfunc=np.mean) | ||
``` | ||
|
||
### Standardizace a teplotní mapa | ||
|
||
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ů. | ||
|
||
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. | ||
|
||
Prakticky normalizace obsahuje dva kroky: | ||
|
||
- 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á. | ||
- 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. | ||
|
||
Nejprve tedy provedeme normalizaci dat. | ||
|
||
```py | ||
food_pivot_norm = (food_pivot - food_pivot.mean()) / food_pivot.std() | ||
``` | ||
|
||
A ve druhém kroku vytvoříme teplotní mapu. | ||
|
||
```py | ||
import seaborn as sns | ||
ax = sns.heatmap(food_pivot_norm) | ||
ax.set(xlabel="Výživná látka", ylabel="Kategorie", title="Množství průměrných látek dle kategorií") | ||
``` | ||
|
||
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
title: Pivot tabulky | ||
lead: Ukážeme si pivot tabulky, které umožňují analyzovat vztah mezi dvěma sloupci tabulky | ||
sections: | ||
- funkce-pivot | ||
- dalsi-funkce |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
--- | ||
title: Dvě kritéria | ||
demand: 3 | ||
--- | ||
|
||
*Poznámka:* Zadání tohoto příkladu ti možná bude připadat povědomé, bylo již v lekci o podmíněném výběru. Pokud jsi ale příklad neřešil(a), nevedí. Pokud ano, uvidíš, že řešení bude díky funkci `pivot()` mnohem jednodušší. | ||
|
||
Připravujeme seznam potravin pro účely lékařského výzkumu, který se bude zabývat kardiovaskulárním systémem. Chceme vybrat pottraviny, které splňují dvě kritéria: | ||
|
||
- nízký obsah nasycených mastných kyselin (`"Fatty acids, total saturated"`, uvažuj méně než 1 gram), | ||
- vysoký obsah vlákniny (`"Fiber, total dietary"`, uvažuj více než 5 gramů). | ||
|
||
Zatímco nasycené mastné kyseliny jsou považovány za spíše škodlivé pro kardiovaskulární systém, vláknina je považována spíše za prospěšnou. Vyber z tabulky `food_nutrient_pivot` potraviny, které vyhovují oběma podmínkám. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
## Pivot tabulky | ||
|
||
Pivot tabulka (často se též používá termín kontingenční tabulka) je nástroj, který vám umožní rychle a efektivně shrnovat, analyzovat, prozkoumávat a prezentovat souhrnná data. | ||
|
||
Jak bychom pivot tabulky mohli využít pro naše data? Pivot tabulky dokážou zobrazit vztah mezi dvěma sloupci tabulky (dvěma proměnnými), v našem případě můžeme například sledovat vztah mezi dvěma výživnými látkami. Mohli bychom tedy zkoumat, jestli při růstu množství jedné výživné látky roste (nebo naopak klesá) množství jiné výživné látky. Dále nám tabulka může usnadnit hledání vhodných potravin na základě více než jednoho kritéria. Pokud bychom například hledali potravinu, která má hodně vlákniny a současně málu nasycených tuků, museli bychom napsat poměrně složitou podmínku. Pivot tabulka nám situaci zjednodušší. Poslední příklad je zkoumání průměrného množství výživných látek v jednotlivých kategoriích potravin, kontingenční tabulky tedy mohou být alternativou k vizualizacím, které jsme i ukázali v minulé lekci. | ||
|
||
Začneme tím, že si načteme data ze souboru `food_nutrient.csv` do tabulky `food_nutrient`. | ||
|
||
```py | ||
import pandas as pd | ||
food_nutrient = pd.read_csv("food_nutrient.csv") | ||
``` | ||
|
||
V `pandas` existuje několik funkcí. My začneme z funkcí `pivot()`. Tato funkce slouží k "přeskládání" tabulky. Výsledná tabulka nebude mít samostatný řádek pro každou kombinaci potraviny a výživné látky. Tabulku přeskládáme tak, aby každá potravina měla pouze jeden řádek a jednotlivé výživné látky budou uloženy ve sloupcích. Namísto sloupce `name` s názvem výživné látky budeme mít názvy výživných látek přímo ve sloupcích. | ||
|
||
Funkci `pivot` určíme čtyři parametry, kromě prvního parametru `data` musíme všechny psát jako pojmenované: | ||
|
||
- Prvním parametrem (`data`) určujeme tabulku, se kterou bude funkce pracovat. | ||
- Parametr `index` slouží jako popisek řádků. V našem případě zvolíme sloupeček `fdc_id`, tj. unikátní číslo potraviny. | ||
- Parametr `columns` bude použit k vytvoření nových sloupečků. Každá unikátní hodnota v tomto sloupci bude znamenat nový sloupeček ve výsledné tabulce. Sem doplníme sloupec `name`. | ||
- Parametr `value` označuje sloupec, ze kterého budou členy hodnoty. V našem případě půjde o sloupec `amount`. Funkce `pivot` se pro každý řádek původní tabulky "podívá" na sloupce `fdc_id` a `name`, tj. na číslo potraviny a název výživné látky. Hodnotu, která je ve sloupci `amount`, pak doplní do nové tabulky na řádek se stejným `fdc_id` a do sloupce pro příslušnou výživnou látku. | ||
|
||
U funkce `pivot()` je důležité, abychom pro každou kombinaci `fdc_id` a `name` měli pouze jeden řádek. Funkce totiž neprovádí žádnou agregaci. Pokud bychom agregaci potřebovali provést, musíme použít některou z funkcí, které si ukážeme dále. | ||
|
||
Níže je použití funkce `pivot`. | ||
|
||
```py | ||
food_nutrient_pivot = pd.pivot(food_nutrient, index="fdc_id", columns="name", values="amount") | ||
``` | ||
|
||
K tabulce `food_nutrient_pivot` můžeme připojit další informace o potravinách, se kterými jsme pracovali v předchozích lekcích. Budeme tedy vědět, kterých potravin se každý řádek týká. | ||
|
||
```py | ||
branded_food = pd.read_csv("branded_food.csv") | ||
food = pd.concat([pd.read_csv("food_sample_100.csv"), pd.read_csv("food_other.csv")], ignore_index=True) | ||
food_brands = pd.merge(food, branded_food, on="fdc_id") | ||
food_nutrient_pivot = pd.merge(food_nutrient_pivot, food_brands, on="fdc_id") | ||
``` | ||
|
||
Po úpravě dat s využitím funkce `pivot()` můžeme snadno vytvořit další typ grafu, a to je :term{cs="bodový graf" en="scatter plot"}. Bodový graf bude mít na svislé i vodorovné ose množství některé z výživných látek. Pomocí bodového grafu uvidíme, jestli může být mezi množstvím výživných látek nějaká souvislost. Vraťme se opět k výzkumu o kardiovaskulárním systému. Pro něj mohou být škodlivé nasycené kyseliny a choresterol. Pomocí bodového grafu se můžeme podívat, jestli mají sýry s větším množstvím nasycených kyselin i větší množství chorestarolu. Graf doplníme popiskem, musíme pro něj využít mírně odlišnou syntaxi. | ||
|
||
```py | ||
import seaborn as sns | ||
|
||
cheese = food_nutrient_pivot[food_nutrient_pivot["branded_food_category"] == "Cheese"] | ||
g = sns.JointGrid(cheese, x="Fatty acids, total saturated", y="Cholesterol") | ||
g.plot_joint(sns.scatterplot) | ||
g.fig.suptitle("Porovnání množství výživných látek v sýrech") | ||
g.ax_joint.set_xlabel("Nasycené kyseliny") | ||
g.ax_joint.set_ylabel("Cholesterol") | ||
``` | ||
|
||
Výsledný graf je na obrázku níže. | ||
|
||
::fig[HTML značka]{src=assets/scatterplot.png size=60} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
--- | ||
title: Dvě kritéria | ||
demand: 3 | ||
--- | ||
|
||
Připravujeme seznam potravin pro účely lékařského výzkumu, který se bude zabývat kardiovaskulárním systémem. Chceme vybrat pottraviny, které splňují dvě kritéria: | ||
pesikj marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- nízký obsah nasycených mastných kyselin (`"Fatty acids, total saturated"`, uvažuj méně než 1 gram), | ||
- vysoký obsah vlákniny (`"Fiber, total dietary"`, uvažuj více než 5 gramů). | ||
|
||
Zatímco nasycené mastné kyseliny jsou považovány za spíše škodlivé pro kardiovaskulární systém, vláknina je považována spíše za prospěšnou. | ||
|
||
Nejprve je potřeba napsat dotaz, který potraviny vybere. Dotaz je poměrně složitý, ale později si v rámci kurzu ukážeme, jak takovou úlohu vyřešit jednodušeji. Je potřeba použít operátor `&` i `|` a závorky, pomocí kterých řídíme, které podmínky se vyhodnocují spolu. Níže jsou rozepsané podmínky, které budeme potřebovat: | ||
|
||
- Ve sloupci `"name"` musí být hodnota `"Fatty acids, total saturated"` a současně ve sloupci `"amount"` hodnota menší než 1. Mezi tyto podmínky vložíme operátor `&`, protože musí být splněné obě. | ||
- Ve sloupci `"name"` musí být hodnota `"Fiber, total dietary"` a současně ve sloupci `"amount"` hodnota vetší než 4. Mezi tyto podmínky vložíme operátor `&`, protože musí být splněné obě. | ||
|
||
Protože obě výživné látky jsou na samostatném řádku, musíme mezi obě podmínky dát operátor `|`. Pokud nějaká potraviny splňuje obě podmínky, bude tedy ve výsledné tabulce dvakrát. Pokud splňuje pouze jednou z podmínek, bude ve výsledné tabulce pouze jednou. Počet výskytů potraviny ve výsledné tabulce můžeme ověřit pomocí metodu `values_count()`. | ||
|
||
U kombinace operátorů `&` a `|` je vhodné uvědomit si, v jaké prioritě by měly být používány. Ač to zní složitě, je to pojem, který už známe z úvodního kurzu z příkladu, kde jsme používali násobení a sčítání v jednom příkladu. Pro operátory `&` a `|` platí, že operátor `&` máš vyšší prioritu než `|`. To nám vyhovuje, protože my chceme nejprve vyhodnotit podmínky s operátorem `&` a poté spojit výsledky s využitím opretáro `|`. | ||
|
||
Níže je tedy struktura, kterou je potřeba upravit, aby řešila popsané podmínky. | ||
|
||
```py | ||
food_nutrient_filtered = food_nutrient[(ve sloupci "name" je hodnota "Fatty acids, total saturated") & (ve sloupci "amount" je hodnota menší než 1) | | ||
(ve sloupci "name" je hodnota "Fiber, total dietary") & (ve sloupci "amount" je hodnota větší než 4)] | ||
``` | ||
|
||
Pokud se úvaze o priotách chceš vyhnout, je možné to vyřešit přidanými závorkami. Tyto závorky nijak neovlivňují, jak Python příkaz vyhodnotí, ale můžou zlepšit čistelnost a pochopitelnost příkazu pro člověka. | ||
|
||
```py | ||
food_nutrient_filtered = food_nutrient[((ve sloupci "name" je hodnota "Fatty acids, total saturated") & (ve sloupci "amount" je hodnota menší než 1)) | | ||
((ve sloupci "name" je hodnota "Fiber, total dietary") & (ve sloupci "amount" je hodnota větší než 4))] | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.