Lekce 12 - Pandas - Zpracování chybějících hodnot Nové
V předchozí lekci, Pandas - Kombinování DataFrame, 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í DataFrame:
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 vyskytují
často 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ékoliv
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
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émkoliv 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
v
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 mí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 použije při použití
bfill()
a všechny NaN
záznamy se tak vyplní:

Při použití metod ffill()
a bfill()
můžeme
taky 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 metoda
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 č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 2x (59.71 kB)
Aplikace je včetně zdrojových kódů v jazyce Python