[2026] Python 데이터 전처리 | 결측치, 이상치, 정규화 완벽 정리

[2026] Python 데이터 전처리 | 결측치, 이상치, 정규화 완벽 정리

이 글의 핵심

import pandas as pd import numpy as np.

들어가며

”좋은 데이터가 좋은 모델을 만든다”

데이터 전처리는 머신러닝의 80%를 차지하는 중요한 과정입니다.

실무 활용 사례: 데이터 분석, 웹 개발, 자동화 프로젝트에서 실제로 사용한 패턴과 코드를 바탕으로 정리했습니다. 초보자가 흔히 겪는 오류와 해결법을 포함합니다.

실무에서 느낀 Python의 매력

처음 Python을 배울 때는 “이게 정말 프로그래밍 언어인가?” 싶을 정도로 간결했습니다. C++에서 10줄로 작성하던 코드가 Python에서는 2~3줄로 끝나는 경우가 많았죠. 특히 데이터 분석 프로젝트를 진행하면서 Pandas와 NumPy의 강력함을 체감했습니다. 엑셀로 몇 시간 걸리던 작업이 Python 스크립트로는 몇 초 만에 끝나는 걸 보고 동료들이 놀라워했던 기억이 납니다. 하지만 처음부터 순탄하지만은 않았습니다. 들여쓰기 하나 잘못해서 몇 시간을 헤맨 적도 있고, 가상환경 설정이 꼬여서 프로젝트 전체를 다시 시작한 적도 있습니다. 이런 시행착오를 겪으며 깨달은 건, 환경 설정을 처음부터 제대로 하는 것이 얼마나 중요한지였습니다. 이 글에서는 제가 겪은 실수들을 바탕으로, 여러분이 같은 시행착오를 겪지 않도록 실전 팁을 담았습니다.

1. 결측치 처리

결측치 확인

표 안에 빈 칸(NaN)이 있으면 장바구니에 가격이 안 적힌 상품처럼 연산이 꼬일 수 있습니다. isnull()로 어디가 비었는지 표를 만들고, 열마다 합을 세어 어느 변수부터 손댈지 정합니다. 아래 코드는 python를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 필요한 모듈 import
import pandas as pd
import numpy as np
df = pd.DataFrame({
    'name': ['철수', '영희', '민수', None],
    'age': [25, None, 28, 30],
    'salary': [3000, 4000, None, 5000]
})
# 결측치 확인
print(df.isnull())
print(df.isnull().sum())  # 열별 결측치 개수

결측치 처리

아래 코드는 python를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 방법 1: 제거
df_dropped = df.dropna()  # 결측치 있는 행 제거
df_dropped = df.dropna(axis=1)  # 결측치 있는 열 제거
# 방법 2: 채우기
df_filled = df.fillna(0)  # 0으로 채우기
df_filled = df.fillna(df.mean())  # 평균으로 채우기
df_filled = df.fillna(method='ffill')  # 앞 값으로 채우기
# 방법 3: 보간
df['age'] = df['age'].interpolate()

2. 이상치 처리

IQR 방법

아래 코드는 python를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# IQR (Interquartile Range)
Q1 = df['salary'].quantile(0.25)
Q3 = df['salary'].quantile(0.75)
IQR = Q3 - Q1
# 이상치 범위
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
# 이상치 제거
df_clean = df[
    (df['salary'] >= lower_bound) & 
    (df['salary'] <= upper_bound)
]

Z-Score 방법

아래 코드는 python를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 코드를 직접 실행해보면서 동작을 확인해보세요.

from scipy import stats
# Z-Score 계산
z_scores = np.abs(stats.zscore(df['salary'].dropna()))
# |Z| > 3인 것을 이상치로 간주
df_clean = df[(z_scores < 3)]

3. 정규화와 표준화

Min-Max 정규화 (0-1)

아래 코드는 python를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 코드를 직접 실행해보면서 동작을 확인해보세요.

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
df['salary_normalized'] = scaler.fit_transform(df[['salary']])
print(df[['salary', 'salary_normalized']])

표준화 (평균 0, 표준편차 1)

아래 코드는 python를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 코드를 직접 실행해보면서 동작을 확인해보세요.

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
df['salary_standardized'] = scaler.fit_transform(df[['salary']])
print(df[['salary', 'salary_standardized']])

4. 범주형 데이터 인코딩

Label Encoding

다음은 python를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

from sklearn.preprocessing import LabelEncoder
df = pd.DataFrame({
    'city': ['서울', '부산', '서울', '대구', '부산']
})
encoder = LabelEncoder()
df['city_encoded'] = encoder.fit_transform(df['city'])
print(df)
#   city  city_encoded
# 0  서울             1
# 1  부산             0
# 2  서울             1
# 3  대구             2
# 4  부산             0

One-Hot Encoding

아래 코드는 python를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# Pandas 사용
df_encoded = pd.get_dummies(df, columns=['city'])
print(df_encoded)
#    city_대구  city_부산  city_서울
# 0       0       0       1
# 1       0       1       0
# 2       0       0       1
# Scikit-learn 사용
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(sparse_output=False)
encoded = encoder.fit_transform(df[['city']])

5. 피처 엔지니어링

새로운 피처 생성

다음은 python를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

df = pd.DataFrame({
    'date': pd.date_range('2024-01-01', periods=100),
    'sales': np.random.randint(100, 500, 100)
})
# 날짜에서 피처 추출
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month
df['day_of_week'] = df['date'].dt.dayofweek
df['is_weekend'] = df['day_of_week'].isin([5, 6]).astype(int)
# 이동 평균
df['sales_ma7'] = df['sales'].rolling(window=7).mean()
# 차분
df['sales_diff'] = df['sales'].diff()

6. 실전 예제

완전한 전처리 파이프라인

다음은 python를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 함수를 통해 로직을 구현합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler, LabelEncoder
def preprocess_data(df):
    """데이터 전처리 파이프라인"""
    
    # 1. 결측치 처리
    numeric_cols = df.select_dtypes(include=[np.number]).columns
    df[numeric_cols] = df[numeric_cols].fillna(df[numeric_cols].mean())
    
    categorical_cols = df.select_dtypes(include=['object']).columns
    df[categorical_cols] = df[categorical_cols].fillna('Unknown')
    
    # 2. 이상치 제거 (IQR)
    for col in numeric_cols:
        Q1 = df[col].quantile(0.25)
        Q3 = df[col].quantile(0.75)
        IQR = Q3 - Q1
        lower = Q1 - 1.5 * IQR
        upper = Q3 + 1.5 * IQR
        df = df[(df[col] >= lower) & (df[col] <= upper)]
    
    # 3. 범주형 인코딩
    for col in categorical_cols:
        le = LabelEncoder()
        df[f'{col}_encoded'] = le.fit_transform(df[col])
    
    # 4. 정규화
    scaler = StandardScaler()
    df[numeric_cols] = scaler.fit_transform(df[numeric_cols])
    
    return df
# 사용
raw_data = pd.read_csv('raw_data.csv')
clean_data = preprocess_data(raw_data)
clean_data.to_csv('clean_data.csv', index=False)

전처리 순서를 정리한 체크리스트

머신러닝 전처리는 요리 전에 재료를 손질하는 과정과 비슷합니다. 먼저 info·describe로 표를 읽고, 결측·이상치·범주 인코딩·스케일링을 모델 가정에 맞게 순서대로 적용합니다. 거리 기반 모델은 스케일이 특히 민감하고, 트리 계열은 상대적으로 덜한 편입니다. 다음은 python를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# ✅ 1. 데이터 확인
df.info()
df.describe()
df.isnull().sum()
# ✅ 2. 결측치 처리
# - 제거 vs 대체 결정
# - 도메인 지식 활용
# ✅ 3. 이상치 처리
# - 시각화로 확인
# - IQR 또는 Z-Score
# ✅ 4. 인코딩
# - 순서 있음: Label Encoding
# - 순서 없음: One-Hot Encoding
# ✅ 5. 스케일링
# - 거리 기반 모델: 필수
# - 트리 기반 모델: 선택

정리

핵심 요약

  1. 결측치: 제거, 대체, 보간
  2. 이상치: IQR, Z-Score
  3. 정규화: Min-Max (0-1)
  4. 표준화: 평균 0, 표준편차 1
  5. 인코딩: Label, One-Hot

다음 단계


관련 글

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3