프로그래밍 (확장)/Python-Pandas
Pandas - 5. 데이터 전처리
개발_노트
2025. 2. 4. 12:05
데이터 전처리
데이터 전처리는 데이터 분석과 모델링의 필수 과정으로, 데이터의 품질을 향상시키고 분석 결과의 신뢰성을 높입니다. 이 문서에서는 Pandas를 활용한 데이터 전처리 기법을 초보자가 이해하기 쉽게 설명하고, 다양한 예제와 함께 각 개념을 소개합니다.
1. 결측치 처리
⚠️ Tip: 결측치를 처리하기 전, 데이터에서 결측치가 발생한 이유를 분석하는 것이 중요합니다. 단순한 입력 오류인지, 특정 패턴이 있는지 확인하세요.
1.1 결측치 확인 (isnull
, notnull
)
import pandas as pd
import numpy as np
# 샘플 데이터 생성
data = {'이름': ['철수', '영희', '민수', np.nan, '현우'],
'나이': [25, np.nan, 22, 27, np.nan],
'점수': [90, 85, np.nan, 76, 95]}
df = pd.DataFrame(data)
# 결측치 확인
print("각 열의 결측치 개수:")
print(df.isnull().sum())
1.2 결측치 채우기 (fillna
)
print("결측치 채우기 전:")
print(df)
# 평균값으로 채우기
df['나이'].fillna(df['나이'].mean(), inplace=True)
print("\n결측치 채운 후:")
print(df)
# 이전 값으로 채우기 (Forward Fill)
df.fillna(method='ffill', inplace=True)
# 다음 값으로 채우기 (Backward Fill)
df.fillna(method='bfill', inplace=True)
1.3 결측치 제거 (dropna
)
# 결측치가 있는 행 제거
df_cleaned = df.dropna()
print("\n결측치 제거 후:")
print(df_cleaned)
2. 중복 데이터 처리
2.1 중복 데이터 확인 (duplicated
)
print("중복된 행 개수:")
print(df.duplicated().sum())
2.2 중복 데이터 제거 (drop_duplicates
)
# 특정 열 기준 중복 제거
df.drop_duplicates(subset=['이름'], keep='first', inplace=True)
print("\n중복 제거 후:")
print(df)
3. 데이터 타입 변환
3.1 데이터 타입 확인 및 변환 (astype
)
# 데이터 타입 변환 전 확인
print("변환 전 데이터 타입:")
print(df.dtypes)
# '나이' 열을 정수형으로 변환
df['나이'] = df['나이'].astype(int)
# float -> int 변환 시 주의사항
df['점수'] = df['점수'].astype(float) # 먼저 float로 변환
df['점수'] = df['점수'].astype(int) # 그 다음 int로 변환
print("\n변환 후 데이터 타입:")
print(df.dtypes)
3.2 날짜 데이터 처리 (pd.to_datetime
)
# 날짜 데이터 변환
df['생년월일'] = pd.to_datetime(['1997-05-12', '2000-08-15',
'1995-07-10', '1999-12-25', '2002-04-03'])
print("\n변환 후 데이터 타입:")
print(df.dtypes)
4. 데이터 정규화 및 표준화
✅ 사용 시나리오:
- MinMaxScaler: 이미지 처리, 음성 신호 등 0~1 범위가 필요한 경우
- StandardScaler: 머신러닝 모델 학습을 위한 연속형 변수 표준화
- RobustScaler: 금융 데이터, 센서 데이터처럼 이상치가 존재하는 경우
from sklearn.preprocessing import MinMaxScaler, StandardScaler, RobustScaler
# 샘플 데이터 생성
data = {'이름': ['철수', '영희', '민수', '지연', '현우'],
'점수': [50, 80, 90, 60, 100]}
df = pd.DataFrame(data)
print("원본 데이터:")
print(df)
# MinMaxScaler 적용
scaler = MinMaxScaler()
df_minmax = df.copy()
df_minmax[['점수']] = scaler.fit_transform(df[['점수']])
print("\nMinMaxScaler 적용 결과:")
print(df_minmax)
# StandardScaler 적용
scaler = StandardScaler()
df_standard = df.copy()
df_standard[['점수']] = scaler.fit_transform(df[['점수']])
print("\nStandardScaler 적용 결과:")
print(df_standard)
# RobustScaler 적용
scaler = RobustScaler()
df_robust = df.copy()
df_robust[['점수']] = scaler.fit_transform(df[['점수']])
print("\nRobustScaler 적용 결과:")
print(df_robust)
5. 이상치(Outlier) 처리
✅ 이상치 탐지 방법 비교:
방법 | 특징 | 장점 | 단점 |
IQR | 사분위수 기반 | 이상치에 덜 민감 | 비대칭 데이터에 부적합 |
Z-score | 정규분포 가정 | 구현 간단 | 극단값에 민감 |
from scipy import stats
# IQR 방식
Q1 = df['점수'].quantile(0.25)
Q3 = df['점수'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers = df[(df['점수'] < lower_bound) | (df['점수'] > upper_bound)]
print("IQR 방식으로 탐지된 이상치:")
print(outliers)
# Z-score 방식
z_scores = stats.zscore(df['점수'])
outliers = df[(z_scores < -3) | (z_scores > 3)]
print("\nZ-score 방식으로 탐지된 이상치:")
print(outliers)
6. 데이터 정렬
# 특정 열 기준 정렬
df_sorted = df.sort_values(by='점수', ascending=False)
print("점수 기준 내림차순 정렬 결과:")
print(df_sorted)
7. 요약 및 결론
- 결측치 처리:
isnull()
,fillna()
,dropna()
- 중복 데이터 처리:
duplicated()
,drop_duplicates()
- 데이터 타입 변환:
astype()
,pd.to_datetime()
- 데이터 정규화/표준화:
MinMaxScaler
,StandardScaler
,RobustScaler
- 이상치 탐지 및 처리:
IQR 방식
,Z-score 방식
- 데이터 정렬:
sort_values()