Prednáška 4: Úvod do Pandas a NumPy¶
Obsah¶
Úvod¶
Dnes sa budeme zaoberať dvoma základnými Python knižnicami, ktoré sú široko používané v dátovej vede a analytike: NumPy a Pandas. Tieto knižnice poskytujú výkonné nástroje pre numerické výpočty a manipuláciu s dátami. Táto prednáška pokryje teoretické aspekty oboch knižníc a ukáže ich použitie prostredníctvom praktických príkladov kódu v prostredí Jupyter Notebook.
Prehľad NumPy¶
Čo je NumPy?¶
NumPy (Numerical Python) je open-source knižnica, ktorá poskytuje podporu pre veľké, viacrozmerné polia a matice, spolu s množstvom vysokoúrovňových matematických funkcií na operáciu týchto polí. Je základným balíčkom pre numerické výpočty v Pythone a slúži ako základ pre mnohé ďalšie knižnice dátovej vedy, vrátane Pandas, SciPy a scikit-learn.
Kľúčové vlastnosti NumPy¶
- N-rozmerné polia: Efektívne spracovanie veľkých datasetov s viacrozmernými poľami.
- Broadcasting: Vykonávanie operácií na poliach rôznych tvarov.
- Matematické funkcie: Široká škála matematických funkcií pre operácie s poľami.
- Lineárna algebra: Podpora operácií lineárnej algebry ako násobenie matíc a dekompozícia.
- Integrácia s C/C++ a Fortran: Umožňuje vysokovýkonné výpočty.
Základné operácie s NumPy¶
- Vytváranie polí: Inicializácia polí pomocou zoznamov, n-tíc alebo vstavaných funkcií.
- Indexovanie a rezanie: Prístup a úprava konkrétnych prvkov alebo sekcií polí.
- Zmeny tvaru a veľkosti: Zmena tvaru polí bez úpravy dát.
- Agregačné funkcie: Výpočet sumarizujúcich štatistík ako priemer, medián a štandardná odchýlka.
- Operácie na prvkoch: Vykonávanie aritmetických operácií na prvkoch poľa.
Príklady kódu¶
import numpy as np
# Vytvorenie NumPy poľa z Python zoznamu
python_zoznam = [1, 2, 3, 4, 5]
np_pole = np.array(python_zoznam)
print("NumPy pole:", np_pole)
# Základné operácie s poľom
print("Tvar poľa:", np_pole.shape)
print("Dátový typ poľa:", np_pole.dtype)
# Vytvorenie viacrozmerného poľa
viacrozmerne = np.array([[1, 2, 3], [4, 5, 6]])
print("Viacrozmerné pole:\n", viacrozmerne)
# Indexovanie a rezanie poľa
print("Prvý prvok:", np_pole[0])
print("Rez [1:4]:", np_pole[1:4])
# Zmena tvaru viacrozmerného poľa
zmenene_tvar = viacrozmerne.reshape(3, 2)
print("Zmenené tvar poľa:\n", zmenene_tvar)
# Agregačné funkcie
print("Priemer:", np_pole.mean())
print("Súčet:", np_pole.sum())
print("Štandardná odchýlka:", np_pole.std())
# Operácie na prvkoch
pole_na_druhou = np_pole ** 2
print("Pole na druhú:", pole_na_druhou)
Prehľad Pandas¶
Čo je Pandas?¶
Pandas je open-source knižnica pre manipuláciu a analýzu dát postavená na vrchole NumPy. Poskytuje dátové štruktúry a funkcie potrebné na prácu so štruktúrovanými dátami hladko a efektívne, čo ju robí nevyhnutným nástrojom pre dátových vedcov a analytikov.
Kľúčové vlastnosti Pandas¶
- DataFrame a Series: Výkonné dátové štruktúry na spracovanie tabulkových a označených dát.
- Zarovnanie dát a integrované spracovanie chýbajúcich dát: Automatické zarovnanie dát a elegantné spracovanie chýbajúcich hodnôt.
- Flexibilná funkčnosť Group By: Umožňuje rozdeľovať dáta do skupín, aplikovať funkcie a kombinovať výsledky.
- Funkcionalita časových radov: Robustná podpora pre dátumy a časy.
- Čítanie/zapisovanie dát: Jednoduché čítanie z a zapisovanie do rôznych formátov súborov ako CSV, Excel, SQL a ďalšie.
Dátové štruktúry v Pandas¶
1. Series¶
Series je jednorozmerné označené pole schopné držať akýkoľvek dátový typ.
import pandas as pd
# Vytvorenie Pandas Series
data = [10, 20, 30, 40, 50]
series = pd.Series(data, index=['a', 'b', 'c', 'd', 'e'])
print("Pandas Series:\n", series)
2. DataFrame¶
DataFrame je dvojrozmerná označená dátová štruktúra s možnosťou rôznych typov údajov v stĺpcoch.
# Vytvorenie Pandas DataFrame z slovníka
data = {
'Meno': ['Alice', 'Bob', 'Charlie'],
'Vek': [25, 30, 35],
'Mesto': ['New York', 'Los Angeles', 'Chicago']
}
df = pd.DataFrame(data)
print("Pandas DataFrame:\n", df)
Základné operácie s Pandas¶
- Načítanie dát: Import dát z rôznych zdrojov ako CSV, Excel, SQL databázy.
- Zobrazenie dát: Zobrazenie prvých niekoľkých riadkov, dátových typov a sumarizujúcich štatistík.
- Výber dát: Prístup k konkrétnym riadkom, stĺpcom alebo podmnožinám dát.
- Čistenie dát: Spracovanie chýbajúcich hodnôt, duplicitných dát a vykonávanie transformácií dát.
- Agregácia a skupinovanie: Zhrnutie dát pomocou agregačných funkcií a skupín podľa kategórií.
- Spájanie a zlučovanie: Kombinácia viacerých DataFrame pomocou rôznych typov join operácií.
Príklady kódu¶
import pandas as pd
# Vytvorenie DataFrame
data = {
'Produkt': ['Notebook', 'Tablet', 'Smartfón', 'Monitor'],
'Cena': [1200, 300, 800, 200],
'Množstvo': [10, 50, 100, 75]
}
df = pd.DataFrame(data)
df
# Zobrazenie informácií o DataFrame
df.info()
# Výber jedného stĺpca
ceny = df['Cena']
ceny
# Výber viacerých stĺpcov
podmnozina = df[['Produkt', 'Množstvo']]
podmnozina
# Filtrovanie riadkov na základe podmienky
drahé_produkty = df[df['Cena'] > 500]
drahé_produkty
# Pridanie nového stĺpca
df['Celková hodnota'] = df['Cena'] * df['Množstvo']
df
# Spracovanie chýbajúcich dát
df_s_nan = df.copy()
df_s_nan.loc[2, 'Cena'] = None
print("\nDataFrame s chýbajúcou hodnotou:\n", df_s_nan)
print("\nSpracovanie chýbajúcich hodnôt nahradením priemerom:")
df_s_nan['Cena'].fillna(df_s_nan['Cena'].mean(), inplace=True)
df_s_nan
# Skupinovanie a agregácia
skupina = df.groupby('Produkt').sum()
skupina
# Spájanie DataFrame
dodatocne_data = {
'Produkt': ['Notebook', 'Tablet', 'Smartfón', 'Monitor'],
'Záruka': ['2 roky', '1 rok', '1 rok', '3 roky']
}
záruka_df = pd.DataFrame(dodatocne_data)
spojeny_df = pd.merge(df, záruka_df, on='Produkt')
spojeny_df
Praktická ukážka¶
Základné nastavenia¶
Pri analýze dát budeme používať viacero knižníc, ktoré je na začiatku potrebné naimportovať do Vášho zápisníka. Knižnica numpy
poskytuje základné typy, ako sú napr. dátové polia reprezentujúce numerické vektory hodnôt, alebo matice. Pri analýze dát budeme najčastejšie pracovať s knižnicou pandas
, ktorá rozširuje numpy
a definuje základné typy pre reprezentáciu dátových tabuliek a ich stĺpcov. Knižnice mathplotlib
a seaborn
budeme používať na vykresľovanie grafov, ktoré sa zobrazia priamo ako súčasť zápisníka.
# importujeme potrebné knižnice, tento odstavec by mal byť spustený ako prvý predtým ako sa budú používať
import pandas as pd
import numpy as np
Dátová množina - Správa o šťastí sveta¶
Správu o šťastí sveta vydáva každoročne Organizácia Spojených Národov a je založená na dátach dotazníkového prieskumu, ktoré sú zozbierané z reprezentatívnej vzorky obyvateľov jednotlivých krajín. Dotazníkový prieskum sa zameriava na hodnotenie vlastného života na základe viacerých kritérií, ktoré zahŕňajú ekonomické ukazovatele, sociálnu starostlivosť, zdravotníctvo, slobodu rozhodovania, vnímanie dobrosrdečnosti medzi ľuďmi a vnímanie korupcie.
Dáta ktoré máte k dispozícii sú vyhodnotené za roky 2015, 2016 a 2017 a sú popísané nasledujúcimi atribútmi:
Country
- Názov krajinyRegion
- Geopolitický región krajinyRank
- Celkové umiestnenie v rebríčku krajín za daný rok, podľa dosiahnutého skóreScore
- Dosiahnuté skóre vyjadrujúce celkové šťastie v krajineGDP
- Ekonomická situácia - hrubý národný produkt na obyvateľaFamily
- Sociálna podpora rodinyHealth
- Stav zdravotníctva - očakávaná dĺžka životaFreedom
- Sloboda prejavu a rozhodovaniaTrust
- Vnímanie korupcieGenerosity
- Vnímanie dobrosrdečnosti
Do celkového hodnotenia je zahrnutý rozdiel medzi danou krajinou a Distópiou - hypotetickou krajinou, ktorá má najnižšie hodnotenie pre všetky ukazovatele (tzn. žiadna krajina na tom nemôže byť horšie ako Distópia).
Načítanie dát a základné štatistiky¶
Dátová tabuľka je v knižnici pandas
reprezentovaná typom DataFrame
(dátový rámec), ktorý je zložený z jednotlivých stĺpcov reprezentovaných typom Series
(dátová postupnosť). pandas
priamo podporuje načítanie a zápis dát v štandardných formátoch ako napr. .csv
(Comma-Separated Values - textový formát s hodnotami oddelenými čiarkou).
# načítame dáta za rok 2015 zo súboru 2015.csv
data_2015 = pd.read_csv("data/2015.csv")
# zobrazíme si názvy stĺpcov (vlasnosť columns je objekt typu pandas.Index, ktorý reprezentuje postupnosť indexov pre
# riadky, alebo stĺpce tabuľky, pristupuje sa k nemu podobne ako ku zoznamu)
data_2015.columns
K dátam sa pristupuje rovnako ako pri zoznamoch, alebo mapách indexovaním. Stĺpce sú štandardne indexované podľa ich názvu a hodnoty v stĺpcoch podľa číselného indexu riadku tabuľky (od 0). Pre každý číselný stĺpec môžeme priamo vypočítať základné štatistiky, ako napr. počet neprázdnych hodnôt, minimum, maximum, priemer, štandardnú odchýlku a kvantily.
# rozmer dátovej tabuľky zistíme z vlastnosti shape
print(data_2015.shape[0]) # prvý rozmer - počet riadkov
print(data_2015.shape[1]) # druhý rozmer - počet stĺpcov
# k dátam pristupujeme indexovaním, napr. vypíšeme hodnotu stĺpca 'Country' na prvom riadku tabuľky (index 0)
print(data_2015['Country'][0])
scores = data_2015['Score'] # scores je objekt typu pandas.Series, ktorý reprezentuje jeden stĺpec tabuľky
# pre číselné stĺpce môžeme vypočítať priamo základné štatistiky
score_count = scores.count() # počet neprázdnych hodnôt
score_mean = scores.mean() # priemerná hodnota
score_std = scores.std() # štandardná odchýlka výberu
score_min = scores.min() # minimálna hodnota
score_max = scores.max() # maximálna hodnota
score_q25 = scores.quantile(0.25) # 25% kvartil
score_q50 = scores.quantile(0.5) # 50% kvartil - medián
score_q75 = scores.quantile(0.75) # 75% kvartil
# štatistiky pre všetky číselné atribúty tabuľky môžeme vypočítať aj naraz pomocou metódy describe()
data_2015.describe()
# pre kategorické atribúty môžeme zobraziť zoznam rôznych hodnôt a ich početnosti
# napr. pre 'Region'
data_2015['Region'].value_counts()
Príprava dát¶
Postupne načítame a upravíme dáta pre roky 2015, 2016 a 2017. Z tabuľky za rok 2015 odstránime stĺpec StdError
, ktorý udáva štandardnú odchýlku odpovedí medzi obyvateľmi jedného štátu a ďalej ho nebudeme pri analýze používať.
# stĺpce sa odstráňujú pomocou metódy drop
# štandardne metóda drop nezmení pôvodný dátový rámec, ale vytvorí nový, takže si zmeníme premennu data_2015
# na novú hodnotu
data_2015 = data_2015.drop(columns="StdError")
# do tabuľky pridáme stĺpec 'Year', ktorého hodnotu nastavíme na 2015 pre všetky riadky
data_2015["Year"] = 2015
# pomocou metódy head si zobrazíme prvé riadky tabuľky (štandardne metóda head vracia nový objekt DataFrame s prvými
# 5 riadkami pôvodnej tabuľky)
data_2015.head()
Načítame dáta za rok 2016 z ktorých odstránime stĺpce LowerConfidence
a UpperConfidence
a pridáme stĺpec Year
s hodnotou 2016 pre všetky riadky.
# načítame dáta za rok 2016
data_2016 = pd.read_csv("data/2016.csv")
# ak v metóde drop nastavíme parameter inplace na True, stĺpec sa odstráni priamo v pôvodnom rámci a nevytvorí sa
# nový, ako parameter columns môžete naraz zadať zoznam viacerých stĺpcov, ktoré sa majú odstrániť
data_2016.drop(columns=["LowerConfidence", "UpperConfidence"], inplace=True)
# pridáme stĺpec Year
data_2016["Year"] = 2016
# pre výpis riadkov môžete pre metódu head zadať počet riadkov, ktoré sa majú zobraziť
data_2016.head(1) # vypíšeme 1 riadok
Z výpisu si môžete všimnúť, že tabuľka za rok 2016 neobsahuje celkové skóre a poradie krajín (stĺpce Score
a Rank
). Keďže Score
a Rank
sú vypočítané spočítaním ostatných ukazovateľov, môžeme ich jednoducho dopočítať metódou eval
. Pre metódu eval
sa výraz pre výpočet hodnôt zadáva ako reťazec, ktorý môže obsahovať názvy existujúcich stĺpcov, konštanty (čísla, reťazce a pod.) a operátory +
, -
, *
, /
, **
, %
.
# pridáme do tabuľky nový stĺpec Score, ktorého hodnotu pre každý riadok vypočítame ako súčet atribútov GDP, Family,
# Health, Freedom, Trust, Generosity a Dystopia
data_2016["Score"] = data_2016.eval("GDP + Family + Health + Freedom + Trust + Generosity + Dystopia")
# stĺpec Rank sa určuje podľa celkového poradia krajín zoradených podľa skóre od najväčšieho po najmenšie
# zoradíme si riadky tabuľky podľa skóre v zostupnom poradí
data_2016.sort_values(by="Score", ascending=False)
# pre kontrolu si zobrazíme 3 prvé a 3 posledné krajiny
data_2016.head(3)
# metóda tail vracia posledné riadky tabuľky
data_2016.tail(3)
# keďže dáta máme zoradené zostupne podľa celkového skóre, hodnoty v stĺpci poradia Rank nastavíme na
# postupnosť čísel 1, 2, ..., počet krajín (počet riadkov v tabuľke)
data_2016["Rank"] = range(1, data_2016.shape[0] + 1)
data_2016.head()
Úloha¶
- Do premennej
data_2017
načítajte dáta za rok 2017 zo súboru2017.csv
. - Odstráňte nepotrebné stĺpce
WhiskerHigh
aWhiskerLow
. - Pridajte stĺpec
Year
a nastavte jeho hodnotu na 2017 pre všetky riadky. - Zobrazte prvý riadok tabuľky.
data_2017 = None
# pomocou metódy concat si spojíme dáta za všetky roky do jednej tabuľky, parameter sort=False a ignore_index=True
# udáva, že sa riadky nemajú preusporiadať podľa ich pôvodných indexov a že sa zachová poradanie v akom sú uvedené
# spájané tabuľky (tzn. najprv všetky riadky 2015, potom 2016 a na koniec 2017)
data = pd.concat([data_2015, data_2016, data_2017], ignore_index=True, sort=False)
data.head(1)
Výber dát¶
Z tabuľky je možné vybrať iba niektoré stĺpce podľa názvu, alebo riadky podľa zadanej podmienky. Pre výber riadkov môžete použiť metódu query
pri ktorej sa logická podmienka zadáva jednoducho ako reťazec podobne ako pri zadávaní výrazov v metóde eval
.
# vyberieme iba stĺpce Contry, Rank, Score a Year
selected = data[["Country", "Rank", "Score", "Year"]]
# vyberieme iba riadky o Slovensku
selected.query("Country == 'Slovakia'")
Alternatívy k query
(napr. pre náš príklad „Country == 'Slovakia'“) sú:
Priama indexácia (maskovanie):
selected[selected["Country"] == "Slovakia"]
Použitie
.loc
:selected.loc[selected["Country"] == "Slovakia"]
V oboch prípadoch ide v podstate o rovnakú logiku – selected["Country"] == "Slovakia"
vytvorí booleovskú masku (True/False pre každý riadok) a Pandas na základe tejto masky vráti len tie riadky, kde je hodnota True (teda Country
má hodnotu 'Slovakia'
).
Metóda .query
je ale výhodná napríklad pri:
- Zložitejších podmienkach (kombinácia viacerých stĺpcov),
- Column names s neobvyklými znakmi (či medzerami),
- Prehľadnosti reťazcovej syntaxy (pripomína SQL).
Ak teda nepotrebujete zvláštnu syntaktickú skratku, booleovská maska s hranatými zátvorkami je najrozšírenejší (a často najjednoduchší) prístup.
# pri filtrovaní riadkov môžete zadať zložitejšiu podmienku s operátormi <, >, <=, >=, !=, ==, in [zoznam],
# not in [zoznam] a s logickými spojkami and, or a not
# napr. odfitrujeme riadky o našich susedoch za rok 2017 a výsledok usporiadame podľa celkového poradia krajín
q = "Country in ['Slovakia', 'Czech Republic', 'Poland', 'Hungary', 'Ukraine', 'Austria'] and Year == 2017"
selected.query(q).sort_values(by="Rank")
Napríklad takto, pomocou booleovského maskovania:
mask = (
selected["Country"].isin(["Slovakia", "Czech Republic", "Poland", "Hungary", "Ukraine", "Austria"])
) & (selected["Year"] == 2017)
selected.loc[mask].sort_values(by="Rank")
Vysvetlenie:
isin([...])
: VrátiTrue
pre riadky, kde je hodnotaCountry
obsiahnutá v zadanom zozname.&
: Logická spojka „a“ (AND).selected.loc[mask]
: Aplikujeme masku naselected
, čím zvolíme len riadky, kde maska vraciaTrue
..sort_values(by="Rank")
: Nakoniec utriedime výstup podľa stĺpcaRank
.
Závislosti medzi atribútmi¶
Jednou zo základných úloh vo fáze pochopenia dát je analyzovať závislosti medzi dvojicami atribútov.
Závislosti medzi kategorickými a číselnými atribútmi¶
Závislosti medzi kategorickými a číselnými atribútmi môžeme skúmať napr. pomocou kontingenčnej tabuľky, ktorá rozdelí dáta do skupín podľa hodnôt kategorických atribútov a zosumarizuje pre každú skupinu hodnoty číselných atribútov pomocou rôznych agregačných funkcií (napr. priemerná/minimálna/maximálne hodnota, štandardná odchýlka výberu atď.)
Kontingenčnú tabuľku vytvoríme pomocou metódy pivot_table
, kde musíme okrem dát zadať aspoň jeden kategorický atribút a jeden číselný.
# napr. na výpočet priemerného skóre pre všetky krajiny v danom roku môžeme zadať
pd.pivot_table(data, index="Year", values="Score")
# dáta môžeme zoskupiť podľa viacerých kategorických atribútov naraz,
# napr. podľa regiónu a roku
pd.pivot_table(data, index=["Region", "Year"], values="Score")
# kontingenčnú tabuľku môžeme preusporiadať presunutím niektorých kategorických atribútov z riadkov tabuľky
# (parameter index) na stĺpce (parameter columns)
# napr. predchádzajúcu tabuľku môžeme prehľadnejšie zobraziť nasledovne
table = pd.pivot_table(data, index="Region", columns="Year", values="Score")
table
# hodnoty kontingenčnej tabuľky si môžeme priamo graficky zobraziť napr. ako horizontálny stĺpcový graf
table.plot(kind="barh")
# v jednej tabuľke môžete vypočítať viacero agregačných funkcií nastavením parametra aggfunc na zoznam funkcií,
# napr. pre výpočet priemernej hodnoty a štandardnej odchýlky skóre pre každý región:
pd.pivot_table(data, index="Region", values="Score", aggfunc=["mean", "std"])
# môžete naraz vypočítať aj rôzne agregačné funkcie pre rôzne číselné atribúty
# napr. v nasledujúcej tabuľke vypočítame priemernú hodnotu pre skóre (Score) a minimálnu a maximálnu hodnotu
# pre poradie (Rank) pre každý región
pd.pivot_table(data, index="Region", values=["Score", "Rank"], aggfunc={"Score": "mean", "Rank": ["min", "max"]})
Závislosti medzi číselnými atribútmi - korelácia¶
Základným typom závislosti medzi dvoma číselnými atribútmi je lineárna závislosť, ktorú je možné vyjadriť (Pearsonovym) korelačným koeficientom.
# vyberieme si iba číselné atribúty ukazovateľov
factors = data[["GDP", "Family", "Health", "Freedom", "Trust", "Generosity"]]
# pomocou metódy corr vypočítame korelačnú tabuľku
corr_table = factors.corr()
corr_table
Na jednoduché grafické zobrazenie môžeme využiť aj základné Pandas funkcie, napríklad factors.plot()
alebo df.hist()
. Tu len ukážeme krátky príklad, ako by mohol vyzerať histogram pre stĺpec GDP
:
# Jednoduche vykreslenie histogramu stlpca GDP v dataset 2015
factors['GDP'].plot(kind='hist', title='Histogram GDP (rok 2015)')
Záver¶
V tejto prednáške sme predstavili dve základné knižnice v ekosystéme Pythonu pre dátovú vedu: NumPy a Pandas.
NumPy poskytuje efektívne ukladanie a manipuláciu s numerickými dátami prostredníctvom svojich výkonných N-rozmerných poľových objektov a súboru matematických funkcií.
Pandas staví na NumPy a ponúka vysokoúrovňové dátové štruktúry ako Series a DataFrame, čo uľahčuje čistenie dát, analýzu a vizualizáciu.
Ovládnutie týchto knižníc je nevyhnutné pre každého dátového profesionála, pretože tvoria základ pre pokročilejšie úlohy manipulácie s dátami, analýzy a strojového učenia.
Referencie¶
- NumPy Dokumentácia: https://numpy.org/doc/
- Pandas Dokumentácia: https://pandas.pydata.org/docs/
- Python for Data Analysis od Wes McKinney: Komplexný sprievodca používaním Pythonových knižníc pre analýzu dát.