Lekce 12 - Pandas - Zpracování chybějících hodnot
V předchozí lekci, Pandas - Kombinování dataframů, jsme si ukázali metody pro kombinování dataframů.
V tomto tutoriálu knihovny Pandas v Pythonu se zaměříme na metody, které nám pomáhají pracovat s chybějícími hodnotami v datech.
Zpracování neúplných dat v Pandas
Než si představíme dnešní téma, pojďme si nejprve importovat testovací data.
Import dat
Budeme pracovat s ukázkovým datasetem zdravotnického sektoru v USA, který obsahuje informace o zaměstnancích, jejich příjmech a dalších detailech. Dataset je k dispozici ke stáhnutí na konci lekce.
Dataset lze načíst pomocí následujícího kódu, do kterého navíc
přidáme několik chybějících hodnot metodou concat(), kterou
jsme si představili v lekci Pandas -
Kombinování dataframů:
import pandas as pd df = pd.read_csv('healthcare.csv') data = { 'EmployeeID': [1414931, 1200301, 1060317, 1812425, 1313912], 'Age': [35, None, 45, None, 40], 'MonthlyIncome': [5000, 6000, None, 7500, 6200], 'Department': ['Cardiology', 'Neurology', 'Cardiology', 'Neurology', 'Radiology'] } df_novy = pd.DataFrame(data) df = pd.concat([df, df_novy], ignore_index=True) df
Dostaneme následující výstup:

Nyní se již můžeme vrhnout na slibované metody.
Metody
V reálné analýze dat se často setkáváme s neúplnými informacemi, a
proto je důležité rozumět nástrojům, které Pandas nabízí. Ukážeme si
metody jako dropna(), isnull(),
notnull(), fillna() a jejich variace, včetně
dalších užitečných postupů jako bfill() nebo
interpolate().
isnull()
Metoda isnull() identifikuje chybějící
hodnoty (NaN) v dataframu. Metoda vrací nový dataframe,
kde jsou chybějící hodnoty označeny jako True a ostatní
hodnoty jako False.
My ji můžeme použít takto:
df.isnull().tail(6)
Zároveň jsme použili metodu tail(), abychom dostali pouze
posledních šest záznamů, neboť jsme si přidali na konec dataframu pět
nových.
Když teď porovnáme posledních pět záznamů s tím úplně nahoře
(index 1675), uvidíme, že se v nových záznamech často
vyskytují hodnoty True vyjadřující chybějící hodnoty:

Chceme-li pouze zjistit, zda dataset obsahuje chybějící hodnoty,
použijeme metodu isnull().any():
df.isnull().any()
Výstupem budou všechny sloupce. U sloupců, kde existují jakékoli
prázdné hodnoty, uvidíme True:

notnull()
Metoda notnull() dělá pravý opak metody
isnull(). Vrátí dataframe s hodnotami True pro
všechny nenulové (validní) hodnoty a
False tam, kde je NaN:
df.notnull().tail(6)
Ve výstupu lze tak snadno ověřit, které buňky neobsahují chybějící hodnotu:

dropna()
Metoda dropna() odstraňuje řádky nebo
sloupce obsahující chybějící hodnoty.
Standardně odstraní celé řádky, pokud v kterémkoli sloupci chybí
hodnota.
Odstranění řádků obsahujících NaN vypadá takto:
df_vycisteny = df.dropna() df_vycisteny
Vidíme, že všechny řádky s hodnotami NaN byly
odstraněny:

Původně jsme měli o pět záznamů více. Byly to právě ty záznamy, které jsme si přidali navíc při importu.
Odstranění řádků na základě specifického sloupce
Pro odstranění řádků s hodnotou NaN v konkrétním sloupci,
například ve sloupci MonthlyIncome, použijeme parametr
subset:
df_vycisteny = df.dropna(subset=['MonthlyIncome'])
df_vycisteny
Vidíme, že byly odstraněny pouze řádky, kde byl NaN ve
sloupci MonthlyIncome:

Vidíme, že počet záznamů je nyní 1680. Původně byl
1681.
fillna()
Metoda fillna() nahrazuje chybějící hodnoty zadanou
hodnotou nebo metodou. Toto je užitečné, pokud
chceme nahradit NaN smysluplnou hodnotou namísto jejich
odstranění.
Kód pro nahrazení NaN pevnou hodnotou vypadá takto:
df_vyplneny = df.fillna(0)
df_vyplneny
Všechny NaN hodnoty byly nahrazeny hodnotou 0:

Nahrazení NaN
průměrnou hodnotou
Pro numerické sloupce můžeme použít statistické hodnoty, například průměrné hodinové mzdy:
prumerne_hodiny = df['HourlyRate'].mean() df['HourlyRate'] = df['HourlyRate'].fillna(prumerne_hodiny) df[['EmployeeID','Age','HourlyRate']]
Hodnota 65.470167 ve výstupu níže odpovídá průměru
sloupce 'HourlyRate':

ffill() a bfill()
Metody ffill (forward fill) a bfill (backward fill)
nahrazují chybějící hodnoty podle sousedních hodnot:
df_ffilled = df.ffill() df_filled[['EmployeeID','Age','DistanceFromHome']]
Metoda ffill nahradí NaN hodnotami z předchozích
řádků. Znamená to tedy, že například ve sloupci
DistanceFromHome uvidíme všude hodnoty 2.0, protože
vrchní řádek (s nejmenším indexem) měl právě hodnotu
2.0:

Pokud bychom to chtěli udělat obráceně, využili bychom metodu
bfill(). V našem případě to ovšem zatím fungovat nebude,
protože poslední záznamy mají hodnotu NaN.
Nastavme tedy poslednímu záznamu nějakou hodnotu pro
DistanceFromHome a poté vyzkoušejme metodu
bfill():
df.loc[df.index[-1], 'DistanceFromHome'] = 10 df_bfilled = df.bfill() df_bfilled[['EmployeeID','Age','DistanceFromHome']]
Po nastavení hodnoty pro poslední záznam ve sloupci
DistanceFromHome se tato hodnota aplikuje při použití
bfill() a všechny NaN záznamy se tak vyplní:

Při použití metod ffill() a bfill() můžeme
také nastavit limit vyplňování pomocí parametru
limit:
df_bfilled = df.bfill(limit=2) df_bfilled[['EmployeeID','Age','DistanceFromHome']].tail()

Vidíme, že zbylé dva záznamy zůstaly s hodnotou NaN.
interpolate()
Poslední metodou, kterou si dnes ukážeme, je interpolate()
pro numerické údaje. Metoda umí dopočítat chybějící
hodnoty na základě okolních validních (nenulových) hodnot. Tato metoda se
využívá především v případech, kdy data mají plynulý (kontinuální)
charakter, například pro časové řady.
Ukažme si dopočítání chybějící hodnoty ve sloupci
Age:
df['Age'] = df['Age'].interpolate() df.tail()
Zde se automaticky použije lineární interpolace, která
"vytvoří" mezilehlé hodnoty mezi dvěma známými čísly. Po zobrazení
dataframu uvidíme, že se ve sloupci Age doplnily chybějící
záznamy (na indexech 1677 a 1679) podle okolních
řádků:

Pokud jsou záznamy v dataframu náhodně seřazené nebo mezi řádky neexistuje logická návaznost (jako například v časové řadě), může interpolace přinést zavádějící výsledky. Lineární interpolace vlastně "předpokládá", že sloupec s daty se plynule mění v rámci indexu řádků, což u tabulek s náhodným pořadím zaměstnanců, měst a podobně nemusí platit. Jestliže je navíc v datech vícero chybějících hodnot jdoucích po sobě, interpolace mezi dvěma vzdálenými body často nedává smysl.
V následujícím kvízu, Kvíz - Práce s řetězci, matematickými daty v Pandas, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 7x (59.71 kB)
Aplikace je včetně zdrojových kódů v jazyce Python

