Python Pandas๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ ์ธํธ์ ๋ณต์กํ ๊ฒฐ์ธก ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ข ํฉ ๊ฐ์ด๋์ ๋๋ค. ์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ์ํ ํ์์ ์ธ ๋์ฒด ๋ฐ ์ ๊ฑฐ ๊ธฐ์ ์ ๋ฐฐ์ฐ์ญ์์ค.
Mastering Python Pandas Data Cleaning: A Global Guide to Missing Value Handling
๋ฐ์ดํฐ ๋ถ์ ๋ฐ ๋จธ์ ๋ฌ๋ ๋ถ์ผ์์ ๋ฐ์ดํฐ ํ์ง์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ๊ฐ์ฅ ํํ๊ฒ ๋ฐ์ํ๋ ๋ฌธ์ ์ค ํ๋๋ ๊ฒฐ์ธก๊ฐ์ ์กด์ฌ์ ๋๋ค. ์ด๋ ๋ฐ์ดํฐ ์ ๋ ฅ ์ค๋ฅ, ์ผ์ ์ค์๋ ๋๋ ๋ถ์์ ํ ์ค๋ฌธ ์กฐ์ฌ ๋ฑ ๋ค์ํ ์์ธ์ผ๋ก ๋ฐ์ํ ์ ์์ต๋๋ค. ๊ฒฐ์ธก ๋ฐ์ดํฐ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ ๋ฐ์ดํฐ ์ ๋ฆฌ ํ๋ก์ธ์ค์ ์ค์ํ ๋จ๊ณ์ด๋ฉฐ ๋ถ์์ ๊ฒฌ๊ณ ์ฑ๊ณผ ๋ชจ๋ธ์ ์ ํ์ฑ์ ๋ณด์ฅํฉ๋๋ค. ์ด ๊ฐ์ด๋์์๋ ์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ์ํด ์ค๊ณ๋ ๊ฐ๋ ฅํ Python Pandas ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒฐ์ธก๊ฐ์ ๊ด๋ฆฌํ๋ ๋ฐ ํ์ํ ํ์ ๊ธฐ์ ์ ์๋ดํฉ๋๋ค.
Why is Handling Missing Values So Crucial?
๊ฒฐ์ธก ๋ฐ์ดํฐ๋ ๊ฒฐ๊ณผ๋ฅผ ํฌ๊ฒ ์๊ณกํ ์ ์์ต๋๋ค. ๋ง์ ๋ถ์ ์๊ณ ๋ฆฌ์ฆ๊ณผ ํต๊ณ ๋ชจ๋ธ์ ๊ฒฐ์ธก๊ฐ์ ์ฒ๋ฆฌํ๋๋ก ์ค๊ณ๋์ง ์์ ์ค๋ฅ๋ ํธํฅ๋ ๊ฒฐ๊ณผ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด:
- Biased Averages: ๊ฒฐ์ธก๊ฐ์ด ํน์ ๊ทธ๋ฃน์ ์ง์ค๋์ด ์๋ ๊ฒฝ์ฐ ํ๊ท ์ ๊ณ์ฐํ๋ฉด ๋ชจ์ง๋จ์ ์ค์ ํน์ฑ์ด ์๋ชป ํํ๋ ์ ์์ต๋๋ค.
- Reduced Sample Size: ๊ฒฐ์ธก๊ฐ์ด ์๋ ํ ๋๋ ์ด์ ๋จ์ํ ์ญ์ ํ๋ฉด ๋ฐ์ดํฐ ์ธํธ๊ฐ ํฌ๊ฒ ์ค์ด๋ค์ด ์ ์ฌ์ ์ผ๋ก ๊ท์คํ ์ ๋ณด์ ํต๊ณ์ ๊ฒ์ ๋ ฅ์ด ์์ค๋ ์ ์์ต๋๋ค.
- Model Performance Degradation: ๋ถ์์ ํ ๋ฐ์ดํฐ๋ก ํ์ต๋ ๋จธ์ ๋ฌ๋ ๋ชจ๋ธ์ ์์ธก ์ฑ๋ฅ ๋ฐ ์ผ๋ฐํ ๊ธฐ๋ฅ์ด ์ ํ๋ ์ ์์ต๋๋ค.
- Misleading Visualizations: ๊ฒฐ์ธก ๋ฐ์ดํฐ ํฌ์ธํธ๊ฐ ๊ณ ๋ ค๋์ง ์์ผ๋ฉด ์ฐจํธ์ ๊ทธ๋ํ๊ฐ ๋ถ์ ํํ ๊ทธ๋ฆผ์ ์ ์ํ ์ ์์ต๋๋ค.
๊ฒฐ์ธก๊ฐ์ ์ดํดํ๊ณ ํด๊ฒฐํ๋ ๊ฒ์ ์ง๋ฆฌ์ ์์น๋ ์ฐ์ ์ ๊ด๊ณ์์ด ๋ชจ๋ ๋ฐ์ดํฐ ์ ๋ฌธ๊ฐ์๊ฒ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ์ ์ ๋๋ค.
Identifying Missing Values in Pandas
Pandas๋ ๊ฒฐ์ธก ๋ฐ์ดํฐ๋ฅผ ๊ฐ์งํ๋ ์ง๊ด์ ์ธ ๋ฉ์๋๋ฅผ ์ ๊ณตํฉ๋๋ค. ๊ฒฐ์ธก๊ฐ์ ๋ํ ์ฃผ์ ํํ์ ์ซ์ ๋ฐ์ดํฐ์ ๊ฒฝ์ฐ NaN (Not a Number)์ด๊ณ ๊ฐ์ฒด ๋ฐ์ดํฐ ์ ํ์ ๊ฒฝ์ฐ None์
๋๋ค. Pandas๋ ๋ ๋ค ๊ฒฐ์ธก์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
The isnull() and notnull() Methods
isnull() ๋ฉ์๋๋ ๋์ผํ ๋ชจ์์ ๋ถ์ธ DataFrame์ ๋ฐํํ์ฌ ๊ฐ์ด ๋๋ฝ๋ ์์น์ True๋ฅผ ๋ํ๋ด๊ณ ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ False๋ฅผ ๋ํ๋
๋๋ค. ๋ฐ๋๋ก notnull()์ ๋๋ฝ๋์ง ์์ ๊ฐ์ ๋ํด True๋ฅผ ๋ฐํํฉ๋๋ค.
import pandas as pd
import numpy as np
# Sample DataFrame with missing values
data = {'col1': [1, 2, np.nan, 4, 5],
'col2': [np.nan, 'b', 'c', 'd', 'e'],
'col3': [6, 7, 8, np.nan, 10]}
df = pd.DataFrame(data)
print("Original DataFrame:")
print(df)
print("\nChecking for null values:")
print(df.isnull())
print("\nChecking for non-null values:")
print(df.notnull())
Counting Missing Values
์ด๋น ๊ฒฐ์ธก๊ฐ ์์ฝ์ ์ป์ผ๋ ค๋ฉด isnull()์ sum() ๋ฉ์๋์ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค.
print("\nNumber of missing values per column:")
print(df.isnull().sum())
์ด ์ถ๋ ฅ์ ๊ฐ ์ด์ ์กด์ฌํ๋ ๋๋ฝ๋ ํญ๋ชฉ ์๋ฅผ ์ ํํ๊ฒ ๋ณด์ฌ์ฃผ์ด ๋ฌธ์ ์ ๋ฒ์๋ฅผ ๋น ๋ฅด๊ฒ ๊ฐ์๋ฅผ ์ ๊ณตํฉ๋๋ค.
Visualizing Missing Data
๋ ํฐ ๋ฐ์ดํฐ ์ธํธ์ ๊ฒฝ์ฐ ๊ฒฐ์ธก ๋ฐ์ดํฐ๋ฅผ ์๊ฐํํ๋ ๊ฒ์ด ๋งค์ฐ ํต์ฐฐ๋ ฅ์ด ์์ ์ ์์ต๋๋ค. missingno์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๊ฒฐ์ธก ํจํด์ ์๋ณํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
# You might need to install this library:
# pip install missingno
import missingno as msno
import matplotlib.pyplot as plt
print("\nVisualizing missing data:")
msno.matrix(df)
plt.title("Missing Data Matrix")
plt.show()
๋งคํธ๋ฆญ์ค ํ๋กฏ์ ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฐ ์ด์ ๋ํด ์กฐ๋ฐํ ๋ง๋๋ฅผ ํ์ํ๊ณ ๋ฐ์ดํฐ๊ฐ ์๋ ๊ณณ์ ํฌ์ ๋ง๋๋ฅผ ํ์ํฉ๋๋ค. ์ด๋ ๊ฒฐ์ธก์ด ์์์ ์ธ์ง ์๋๋ฉด ํจํด์ ๋ฐ๋ฅด๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ผ ์ ์์ต๋๋ค.
Strategies for Handling Missing Values
๊ฒฐ์ธก ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ๋ ๋ช ๊ฐ์ง ์ผ๋ฐ์ ์ธ ์ ๋ต์ด ์์ต๋๋ค. ์ ๋ต ์ ํ์ ์ข ์ข ๋ฐ์ดํฐ์ ํน์ฑ, ๊ฒฐ์ธก๊ฐ์ ๋น์จ ๋ฐ ๋ถ์ ๋ชฉํ์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค.
1. Deletion Strategies
์ญ์ ๋ ๊ฒฐ์ธก๊ฐ์ด ์๋ ๋ฐ์ดํฐ ํฌ์ธํธ๋ฅผ ์ ๊ฑฐํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ๊ฒ๋ณด๊ธฐ์๋ ๊ฐ๋จํ์ง๋ง ๊ทธ ์๋ฏธ๋ฅผ ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
a. Row Deletion (Listwise Deletion)
์ด๊ฒ์ ๊ฐ์ฅ ๊ฐ๋จํ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค. ํ๋ ์ด์์ ๊ฒฐ์ธก๊ฐ์ด ์๋ ์ ์ฒด ํ์ ์ ๊ฑฐํฉ๋๋ค.
print("\nDataFrame after dropping rows with any missing values:")
df_dropped_rows = df.dropna()
print(df_dropped_rows)
Pros: ๊ตฌํ์ด ๊ฐ๋จํ๊ณ ๊ฒฐ์ธก๊ฐ์ ์ฒ๋ฆฌํ ์ ์๋ ์๊ณ ๋ฆฌ์ฆ์ ์ ํฉํ ๊นจ๋ํ ๋ฐ์ดํฐ ์ธํธ๋ฅผ ๋ง๋ญ๋๋ค.
Cons: ๋ฐ์ดํฐ ์ธํธ ํฌ๊ธฐ๊ฐ ํฌ๊ฒ ์ค์ด๋ค์ด ์ ์ฌ์ ์ผ๋ก ๊ท์คํ ์ ๋ณด๊ฐ ์์ค๋๊ณ ๊ฒฐ์ธก์ด ์์ ํ ์์์ ์ด์ง ์์ ๊ฒฝ์ฐ ํธํฅ์ด ๋ฐ์ํ ์ ์์ต๋๋ค (MCAR - Missing Completely At Random).
b. Column Deletion
ํน์ ์ด์ ๊ฒฐ์ธก๊ฐ์ ๋น์จ์ด ๋งค์ฐ ๋๊ณ ๋ถ์์ ์ค์ํ์ง ์์ ๊ฒฝ์ฐ ์ ์ฒด ์ด์ ์ญ์ ํ๋ ๊ฒ์ ๊ณ ๋ คํ ์ ์์ต๋๋ค.
# Example: Drop 'col1' if it had too many missing values (hypothetically)
# For demonstration, let's create a scenario with more missing data in col1
data_high_missing = {'col1': [1, np.nan, np.nan, np.nan, 5],
'col2': [np.nan, 'b', 'c', 'd', 'e'],
'col3': [6, 7, 8, np.nan, 10]}
df_high_missing = pd.DataFrame(data_high_missing)
print("\nDataFrame with potentially high missingness in col1:")
print(df_high_missing)
print("\nMissing values per column:")
print(df_high_missing.isnull().sum())
# Let's say we decide to drop col1 due to high missingness
df_dropped_col = df_high_missing.drop('col1', axis=1) # axis=1 indicates dropping a column
print("\nDataFrame after dropping col1:")
print(df_dropped_col)
Pros: ์ด์ด ๊ฒฐ์ธก ๋ฐ์ดํฐ๋ก ์ธํด ๋๋ถ๋ถ ์ ์ฉํ์ง ์์ ๊ฒฝ์ฐ ํจ๊ณผ์ ์ ๋๋ค.
Cons: ๊ท์คํ ๊ธฐ๋ฅ์ด ์์ค๋ ์ ์์ต๋๋ค. "๋๋ฌด ๋ง์ ๊ฒฐ์ธก๊ฐ"์ ๋ํ ์๊ณ๊ฐ์ ์ฃผ๊ด์ ์ ๋๋ค.
2. Imputation Strategies
๋์ฒด๋ ๊ฒฐ์ธก๊ฐ์ ์ถ์ ๋๋ ๊ณ์ฐ๋ ๊ฐ์ผ๋ก ๋์ฒดํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ๋ฐ์ดํฐ ์ธํธ ํฌ๊ธฐ๋ฅผ ๋ณด์กดํ๋ฏ๋ก ์ญ์ ๋ณด๋ค ์ ํธ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
a. Mean/Median/Mode Imputation
์ด๊ฒ์ ์ผ๋ฐ์ ์ด๊ณ ๊ฐ๋จํ ๋์ฒด ๊ธฐ์ ์ ๋๋ค. ์ซ์ ์ด์ ๊ฒฝ์ฐ ํด๋น ์ด์์ ๊ฒฐ์ธก๊ฐ์ด ์๋ ๊ฐ์ ํ๊ท ๋๋ ์ค์๊ฐ์ผ๋ก ๊ฒฐ์ธก๊ฐ์ ๋์ฒดํ ์ ์์ต๋๋ค. ๋ฒ์ฃผํ ์ด์ ๊ฒฝ์ฐ ์ต๋น๊ฐ (๊ฐ์ฅ ๋น๋ฒํ ๊ฐ)์ด ์ฌ์ฉ๋ฉ๋๋ค.
- Mean Imputation: ์ ๊ท ๋ถํฌ ๋ฐ์ดํฐ์ ์ ํฉํฉ๋๋ค. ์ด์์น์ ๋ฏผ๊ฐํฉ๋๋ค.
- Median Imputation: ํ๊ท ๋์ฒด๋ณด๋ค ์ด์์น์ ๋ ๊ฐ๋ ฅํฉ๋๋ค.
- Mode Imputation: ๋ฒ์ฃผํ ๊ธฐ๋ฅ์ ์ฌ์ฉ๋ฉ๋๋ค.
# Using the original df with some NaN values
print("\nOriginal DataFrame for imputation:")
print(df)
# Impute missing values in 'col1' with the mean
mean_col1 = df['col1'].mean()
df['col1'].fillna(mean_col1, inplace=True)
# Impute missing values in 'col3' with the median
median_col3 = df['col3'].median()
df['col3'].fillna(median_col3, inplace=True)
# Impute missing values in 'col2' with the mode
mode_col2 = df['col2'].mode()[0] # mode() can return multiple values if there's a tie
df['col2'].fillna(mode_col2, inplace=True)
print("\nDataFrame after mean/median/mode imputation:")
print(df)
Pros: ๊ฐ๋จํ๊ณ ๋ฐ์ดํฐ ์ธํธ ํฌ๊ธฐ๋ฅผ ๋ณด์กดํฉ๋๋ค.
Cons: ๋ฐ์ดํฐ์ ๋ถ์ฐ ๋ฐ ๊ณต๋ถ์ฐ์ ์๊ณกํ ์ ์์ต๋๋ค. ํ๊ท /์ค์๊ฐ/์ต๋น๊ฐ์ด ๊ฒฐ์ธก ๋ฐ์ดํฐ์ ๋ํ ์ข์ ๋ํ๊ฐ์ด๋ผ๊ณ ๊ฐ์ ํ์ง๋ง ํญ์ ์ฌ์ค์ ์๋ ์ ์์ต๋๋ค.
b. Forward Fill and Backward Fill
์ด๋ฌํ ๋ฉ์๋๋ ์๊ณ์ด ๋ฐ์ดํฐ ๋๋ ์์ฐ์ค๋ฌ์ด ์์๊ฐ ์๋ ๋ฐ์ดํฐ์ ํนํ ์ ์ฉํฉ๋๋ค.
- Forward Fill (
ffill): ๊ฒฐ์ธก๊ฐ์ ๋ง์ง๋ง์ผ๋ก ์๋ ค์ง ์ ํจํ ๊ด์ธก๊ฐ์ผ๋ก ์ฑ์๋๋ค. - Backward Fill (
bfill): ๊ฒฐ์ธก๊ฐ์ ๋ค์์ผ๋ก ์๋ ค์ง ์ ํจํ ๊ด์ธก๊ฐ์ผ๋ก ์ฑ์๋๋ค.
# Recreate a DataFrame with missing values suitable for ffill/bfill
data_time_series = {'value': [10, 12, np.nan, 15, np.nan, np.nan, 20]}
df_ts = pd.DataFrame(data_time_series)
print("\nOriginal DataFrame for time-series imputation:")
print(df_ts)
# Forward fill
df_ts_ffill = df_ts.fillna(method='ffill')
print("\nDataFrame after forward fill:")
print(df_ts_ffill)
# Backward fill
df_ts_bfill = df_ts.fillna(method='bfill')
print("\nDataFrame after backward fill:")
print(df_ts_bfill)
Pros: ์ ๋ ฌ๋ ๋ฐ์ดํฐ์ ์ ์ฉํ๊ณ ์๊ฐ์ ๊ด๊ณ๋ฅผ ๋ณด์กดํฉ๋๋ค.
Cons: ๊ฒฐ์ธก ๋ฐ์ดํฐ์ ๊ฐ๊ฒฉ์ด ๊ธธ๋ฉด ์๋ชป๋ ๊ฐ์ ์ ํํ ์ ์์ต๋๋ค. ffill์ ๋ฏธ๋ ์ ๋ณด๋ฅผ ๊ณ ๋ คํ์ง ์๊ณ bfill์ ๊ณผ๊ฑฐ ์ ๋ณด๋ฅผ ๊ณ ๋ คํ์ง ์์ต๋๋ค.
c. Imputation using Groupby
๋ณด๋ค ์ ๊ตํ ์ ๊ทผ ๋ฐฉ์์ ๊ทธ๋ฃน ํต๊ณ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ฒฐ์ธก๊ฐ์ ๋์ฒดํ๋ ๊ฒ์ ๋๋ค. ์ด๋ ๊ฒฐ์ธก์ด ๋ฐ์ดํฐ ๋ด์ ํน์ ๋ฒ์ฃผ ๋๋ ๊ทธ๋ฃน๊ณผ ๊ด๋ จ์ด ์๋ค๊ณ ์์ฌ๋๋ ๊ฒฝ์ฐ ํนํ ์ ์ฉํฉ๋๋ค.
data_grouped = {
'category': ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B'],
'value': [10, 20, np.nan, 25, 15, 30, 12, np.nan]
}
df_grouped = pd.DataFrame(data_grouped)
print("\nOriginal DataFrame for grouped imputation:")
print(df_grouped)
# Impute missing 'value' based on the mean 'value' of each 'category'
df_grouped['value'] = df_grouped.groupby('category')['value'].transform(lambda x: x.fillna(x.mean()))
print("\nDataFrame after grouped mean imputation:")
print(df_grouped)
Pros: ๊ทธ๋ฃน ๊ฐ์ ๋ณ๋์ ๊ณ ๋ คํ์ฌ ์ข ์ข ๊ธ๋ก๋ฒ ํ๊ท /์ค์๊ฐ/์ต๋น๊ฐ๋ณด๋ค ๋ ์ ํํ ๋์ฒด๋ก ์ด์ด์ง๋๋ค.
Cons: ๊ด๋ จ ๊ทธ๋ฃนํ ๋ณ์๊ฐ ํ์ํฉ๋๋ค. ๋งค์ฐ ํฐ ๋ฐ์ดํฐ ์ธํธ์ ๊ฒฝ์ฐ ๊ณ์ฐ ์ง์ฝ์ ์ผ ์ ์์ต๋๋ค.
d. More Advanced Imputation Techniques
ํนํ ๋จธ์ ๋ฌ๋ ํ์ดํ๋ผ์ธ์์ ๋ณด๋ค ๋ณต์กํ ์๋๋ฆฌ์ค์ ๊ฒฝ์ฐ ๋ค์๊ณผ ๊ฐ์ ๊ณ ๊ธ ๋ฐฉ๋ฒ์ ๊ณ ๋ คํ์ญ์์ค.
- K-Nearest Neighbors (KNN) Imputer: ํ๋ จ ์ธํธ์์ ์ฐพ์ K๊ฐ์ ๊ฐ์ฅ ๊ฐ๊น์ด ์ด์์ ๊ฐ์ ์ฌ์ฉํ์ฌ ๊ฒฐ์ธก๊ฐ์ ๋์ฒดํฉ๋๋ค.
- Iterative Imputer (e.g., using MICE - Multiple Imputation by Chained Equations): ๊ฒฐ์ธก๊ฐ์ด ์๋ ๊ฐ ๊ธฐ๋ฅ์ ๋ค๋ฅธ ๊ธฐ๋ฅ์ ํจ์๋ก ๋ชจ๋ธ๋งํ๊ณ ๋ฐ๋ณต์ ์ธ ๋ฒ ์ด์ง์ ํ๋ ฌ ์์ฑ์ ์ฌ์ฉํ์ฌ ๋์ฒดํฉ๋๋ค.
- Regression Imputation: ํ๊ท ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ๊ฒฐ์ธก๊ฐ์ ์์ธกํฉ๋๋ค.
์ด๋ฌํ ๋ฉ์๋๋ ์ผ๋ฐ์ ์ผ๋ก Scikit-learn๊ณผ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
# Example using Scikit-learn's KNNImputer
from sklearn.impute import KNNImputer
# KNNImputer works on numerical data. We'll use a sample numerical DataFrame.
data_knn = {'A': [1, 2, np.nan, 4, 5],
'B': [np.nan, 20, 30, 40, 50],
'C': [100, np.nan, 300, 400, 500]}
df_knn = pd.DataFrame(data_knn)
print("\nOriginal DataFrame for KNN imputation:")
print(df_knn)
imputer = KNNImputer(n_neighbors=2) # Use 2 nearest neighbors
df_knn_imputed_arr = imputer.fit_transform(df_knn)
df_knn_imputed = pd.DataFrame(df_knn_imputed_arr, columns=df_knn.columns)
print("\nDataFrame after KNN imputation:")
print(df_knn_imputed)
Pros: ๊ธฐ๋ฅ ๊ฐ์ ๊ด๊ณ๋ฅผ ๊ณ ๋ คํ์ฌ ๋ ์ ํํ ๋์ฒด๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค.
Cons: ๊ณ์ฐ ๋น์ฉ์ด ๋ ๋ง์ด ๋ค๊ณ ์ ์คํ ๊ตฌํ์ด ํ์ํ๋ฉฐ ๊ธฐ๋ฅ ๊ด๊ณ์ ๋ํ ๊ฐ์ ์ด ์ ์ง๋์ด์ผ ํฉ๋๋ค.
Handling Missing Values in Categorical Data
๋ฒ์ฃผํ ๋ฐ์ดํฐ๋ ์์ฒด์ ์ธ ์ผ๋ จ์ ๋ฌธ์ ๋ฅผ ์ ์ํฉ๋๋ค. ์ต๋น๊ฐ ๋์ฒด๊ฐ ์ผ๋ฐ์ ์ด์ง๋ง ๋ค๋ฅธ ์ ๋ต๋ ํจ๊ณผ์ ์ ๋๋ค.
- Mode Imputation: ์์์์ ๊ฐ์ด ๊ฐ์ฅ ๋น๋ฒํ ๋ฒ์ฃผ๋ก ์ฑ์๋๋ค.
- Creating a New Category: ๊ฒฐ์ธก๊ฐ์ ๋ณ๋์ ๋ฒ์ฃผ๋ก ์ฒ๋ฆฌํฉ๋๋ค (์: "Unknown", "Missing"). ๋ฐ์ดํฐ๊ฐ ๋๋ฝ๋์๋ค๋ ์ฌ์ค ์์ฒด๊ฐ ์ ์ตํ ๊ฒฝ์ฐ์ ์ ์ฉํฉ๋๋ค.
- Imputation based on other features: ๋ฒ์ฃผํ ๊ธฐ๋ฅ๊ณผ ๋ค๋ฅธ ๊ธฐ๋ฅ ๊ฐ์ ๊ฐ๋ ฅํ ๊ด๊ณ๊ฐ ์๋ ๊ฒฝ์ฐ ๋ถ๋ฅ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋๋ฝ๋ ๋ฒ์ฃผ๋ฅผ ์์ธกํ ์ ์์ต๋๋ค.
data_cat = {'Product': ['A', 'B', 'A', 'C', 'B', 'A', np.nan],
'Region': ['North', 'South', 'East', 'West', 'North', np.nan, 'East']}
df_cat = pd.DataFrame(data_cat)
print("\nOriginal DataFrame for categorical handling:")
print(df_cat)
# Strategy 1: Mode imputation for 'Region'
mode_region = df_cat['Region'].mode()[0]
df_cat['Region'].fillna(mode_region, inplace=True)
# Strategy 2: Create a new category for 'Product'
df_cat['Product'].fillna('Unknown', inplace=True)
print("\nDataFrame after categorical imputation:")
print(df_cat)
Best Practices and Considerations for a Global Audience
๋ค์ํ ์์ค์ ๋ฐ์ดํฐ๋ก ์์ ํ๊ณ ์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ์ํด ์์ ํ๋ ๊ฒฝ์ฐ ๋ค์์ ๊ณ ๋ คํ์ญ์์ค.
- Understand the Data Source: ์ ๊ฐ์ด ๋๋ฝ๋์์ต๋๊น? ํน์ ์ง์ญ ๋๋ ํ๋ซํผ์ ๋ฐ์ดํฐ ์์ง์ ์์คํ ๋ฌธ์ ๊ฐ ์์ต๋๊น? ์ถ์ฒ๋ฅผ ์๋ฉด ์ ๋ต์ ์๋ดํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ์ค๋ฌธ ์กฐ์ฌ ํ๋ซํผ์ด ํน์ ๊ตญ๊ฐ์์ ํน์ ์ธ๊ตฌ ํต๊ณ๋ฅผ ์ง์์ ์ผ๋ก ์บก์ฒํ์ง ๋ชปํ๋ ๊ฒฝ์ฐ ํด๋น ๊ฒฐ์ธก์ ์์์ ์ด์ง ์์ ์ ์์ต๋๋ค.
- Context is Key: ๊ฒฐ์ธก๊ฐ์ ์ฒ๋ฆฌํ๋ '์ฌ๋ฐ๋ฅธ' ๋ฐฉ๋ฒ์ ์ํฉ์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค. ๊ธ์ต ๋ชจ๋ธ์ ์์ ํธํฅ์กฐ์ฐจ ํผํ๊ธฐ ์ํด ๊ผผ๊ผผํ ๋์ฒด๊ฐ ํ์ํ ์ ์์ง๋ง ๋น ๋ฅธ ํ์์ ๋ถ์์๋ ๋ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ผ๋ก ์ถฉ๋ถํ ์ ์์ต๋๋ค.
- Cultural Nuances in Data: ๋ฐ์ดํฐ ์์ง ๋ฐฉ๋ฒ์ ๋ฌธํ๊ถ๋ง๋ค ๋ค๋ฅผ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด "์๋"์ด ๋ณด๊ณ ๋๋ ๋ฐฉ์ ๋๋ "ํด๋น ์์"์ด ์ผ๋ฐ์ ์ธ ์๋ต์ธ์ง ์ฌ๋ถ๋ ๋ค๋ฅผ ์ ์์ต๋๋ค. ์ด๋ ๊ฒฐ์ธก๊ฐ์ด ํด์๋๊ณ ์ฒ๋ฆฌ๋๋ ๋ฐฉ์์ ์ํฅ์ ์ค ์ ์์ต๋๋ค.
- Time Zones and Data Lag: ๋ค๋ฅธ ์๊ฐ๋์ ์๊ณ์ด ๋ฐ์ดํฐ์ ๊ฒฝ์ฐ ffill/bfill๊ณผ ๊ฐ์ ์๊ฐ ๊ธฐ๋ฐ ๋์ฒด ๋ฐฉ๋ฒ์ ์ ์ฉํ๊ธฐ ์ ์ ๋ฐ์ดํฐ๊ฐ ํ์คํ๋์๋์ง ํ์ธํฉ๋๋ค (์: UTC๋ก).
- Currency and Units: ์๋ก ๋ค๋ฅธ ํตํ ๋๋ ๋จ์๋ฅผ ํฌํจํ๋ ์ซ์ ๊ฐ์ ๋์ฒดํ ๋ ๋์ฒดํ๊ธฐ ์ ์ ์ผ๊ด์ฑ ๋๋ ์ ์ ํ ๋ณํ์ ํ์ธํฉ๋๋ค.
- Document Your Decisions: ํญ์ ๊ฒฐ์ธก ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ ์ฌ์ฉํ ๋ฐฉ๋ฒ์ ๋ฌธ์ํํ์ญ์์ค. ์ด ํฌ๋ช ์ฑ์ ์ฌํ์ฑ์ ๋งค์ฐ ์ค์ํ๋ฉฐ ๋ค๋ฅธ ์ฌ๋๋ค์ด ๋ถ์์ ์ดํดํ๋ ๋ฐ ์ค์ํฉ๋๋ค.
- Iterative Process: ๊ฒฐ์ธก๊ฐ ์ฒ๋ฆฌ๋ฅผ ํฌํจํ ๋ฐ์ดํฐ ์ ๋ฆฌ๋ ์ข ์ข ๋ฐ๋ณต์ ์ธ ํ๋ก์ธ์ค์ ๋๋ค. ํ ๊ฐ์ง ๋ฐฉ๋ฒ์ ์๋ํ๊ณ ๊ทธ ์ํฅ์ ํ๊ฐํ ๋ค์ ์ ๊ทผ ๋ฐฉ์์ ๊ฐ์ ํ ์ ์์ต๋๋ค.
- Use Libraries Wisely: Pandas๋ ๊ธฐ๋ณธ ๋๊ตฌ์ด์ง๋ง ๋ณด๋ค ๋ณต์กํ ๋์ฒด์ ๊ฒฝ์ฐ Scikit-learn์ ๋งค์ฐ ๊ท์คํฉ๋๋ค. ์์ ์ ์ ํฉํ ๋๊ตฌ๋ฅผ ์ ํํ์ญ์์ค.
Conclusion
๊ฒฐ์ธก๊ฐ์ ์ค์ ๋ฐ์ดํฐ ์์ ์ ๋ถ๊ฐํผํ ๋ถ๋ถ์ ๋๋ค. Python Pandas๋ ์ด๋ฌํ ๋๋ฝ๋ ํญ๋ชฉ์ ์๋ณ, ๋ถ์ ๋ฐ ์ฒ๋ฆฌํ ์ ์๋ ์ ์ฐํ๊ณ ๊ฐ๋ ฅํ ๋๊ตฌ ์ธํธ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ญ์ ๋๋ ๋์ฒด๋ฅผ ์ ํํ๋ ๊ฐ ๋ฐฉ๋ฒ์๋ ์์ฒด์ ์ธ ์ ์ถฉ์ ์ด ์์ต๋๋ค. ์ด๋ฌํ ๊ธฐ์ ์ ์ดํดํ๊ณ ๋ฐ์ดํฐ์ ์ ์ญ ์ปจํ ์คํธ๋ฅผ ๊ณ ๋ คํจ์ผ๋ก์จ ๋ฐ์ดํฐ ๋ถ์ ๋ฐ ๋จธ์ ๋ฌ๋ ๋ชจ๋ธ์ ํ์ง๊ณผ ์ ๋ขฐ์ฑ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค. ์ด๋ฌํ ๋ฐ์ดํฐ ์ ๋ฆฌ ๊ธฐ์ ์ ๋ง์คํฐํ๋ ๊ฒ์ ์ธ๊ณ ์ด๋ ๊ณณ์์๋ ํจ๊ณผ์ ์ธ ๋ฐ์ดํฐ ์ ๋ฌธ๊ฐ๊ฐ ๋๋ ๋ฐ ์์ด ์ด์์ ๋๋ค.
Key Takeaways:
- Identify:
df.isnull().sum()๋ฐ ์๊ฐํ๋ฅผ ์ฌ์ฉํ์ญ์์ค. - Delete: ๋ฐ์ดํฐ ์์ค์ ์ธ์ํ๋ฉด์
dropna()๋ฅผ ์ ์คํ๊ฒ ์ฌ์ฉํ์ญ์์ค. - Impute: ํ๊ท , ์ค์๊ฐ, ์ต๋น๊ฐ, ffill, bfill ๋๋ Scikit-learn์ ๊ณ ๊ธ ๊ธฐ์ ๊ณผ ํจ๊ป
fillna()๋ฅผ ์ฌ์ฉํ์ญ์์ค. - Context Matters: ์ต์์ ์ ๋ต์ ๋ฐ์ดํฐ์ ๋ชฉํ์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค.
- Global Awareness: ๋ฌธํ์ ๋์์ค์ ๋ฐ์ดํฐ ์ถ์ฒ๋ฅผ ๊ณ ๋ คํ์ญ์์ค.
์ด๋ฌํ ๊ธฐ์ ์ ๊ณ์ ์ฐ์ตํ๋ฉด ๊ฐ๋ ฅํ ๋ฐ์ดํฐ ๊ณผํ ์ํฌํ๋ก๋ฅผ ์ํ ๊ฐ๋ ฅํ ๊ธฐ๋ฐ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.