[2025.11.18] 오늘의 학습 키워드 - 파이썬 이상치&결측치의 처리

허진원·2025년 11월 18일

내일배움캠프 TIL

목록 보기
23/41

날이 갑작스럽게 추워진 듯하다. 바람도 많이 부는 듯하다.

추워진 탓인가, 인터넷 연결도 어쩐지 버벅거리는 듯하다. 머리도 얼어 붙었는지 잠에서 깨는 것도 쉽지가 않다.

목감기는 다행히도 악화되지는 않았다. 오히려 전날보다 통증이 줄어들기도 했다. 몸관리를 잘 해서 좋은 컨디션으로 남은 캠프 일정을 잘 소화해낼 수 있도록 노력해야겠다.

  1. 오늘 학습 키워드
    파이썬 이상치 및 결측치 처리하기 연습
  1. 오늘 학습한 내용을 나만의 언어로 정리하기
    오늘은 파이썬에서 데이터의 결측치와 이상치를 확인해보고, 이를 처리하는 과정에 대해서 학습했다.

오늘의 학습 목표는 다음과 같다.

  • 데이터의 결측치(Missing Value)이상치(Outlier) 개념 이해
  • Python 라이브러리를 활용해 실제 데이터셋에서 결측치와 이상치를 탐지·처리하는 방법 학습
  • 데이터 분석(EDA) 과정에서 데이터 정제(Data Cleaning)의 중요성 체득

어떤 데이터베이스이든 반드시 오류가 있다. 이를 처리하지 않은 채로 데이터 분석을 시도하면 잘못된 데이터를 가지고 결과를 측정하게 된다. 따라서 데이터를 분석하기 전에 반드시 EDA 과정을 밟아야만 한다.

  1. 학습 내용

🗂️ 주요 학습 내용

1. 결측치(Missing Value)

  • 정의: 데이터 수집 과정에서 누락된 값
  • 처리 방법
    • 제거(dropna): 결측치가 있는 행/열 삭제, 데이터 손실이 발생할 수 있음
    • 대체(fillna): 최빈값, 평균값, 중앙값, 앞/뒤 값, groupby 결과 등으로 채움

🧩 결측치 처리 코드 예제

import pandas as pd


# 결측치 확인
print(df.isnull().sum())

# 1. 결측치 제거
# 열 제거
df3 = df3.drop('Unnamed: 4', axis=1)

# 행 제거
df3 = df3.dropna()
df3 = df3.dropna(axis=0, how='any')

# 전체 행이 결측치인 경우만 제거
df3 = df3.dropna(how='all')

# inplace 옵션으로 바로 저장
df3.dropna(inplace=True)


# 2. 결측치 대체
# 최빈값 대체
df3['Interaction type'] = df3['Interaction type'].fillna(df3['Interaction type'].mode()[0])

# 평균값 대체
df['sw'] = df['sw'].fillna(df['sw'].mean())

# 중앙값 대체
df['sw'] = df['sw'].fillna(df['sw'].median())

# 바로 위 값으로 대체
df['sw'] = df['sw'].fillna(method='ffill')

# 바로 아래 값으로 대체
df['sw'] = df['sw'].fillna(method='bfill')

# groupby 결과로 대체
df['sw'] = df['sw'].fillna(df.groupby('Is Amazon Seller')['sw'].transform('median'))

2. 이상치(Outlier)

  • 정의: 정상 범위를 벗어난 극단적인 값
  • 탐색 기법
    • Z-Score: 정규분포 기반, ±3 이상이면 이상치
    • IQR: 사분위 범위(Q1, Q3) 기준으로 벗어난 값
    • Isolation Forest, DBScan: 머신러닝/클러스터링 기반 (개념 설명)
  • 처리 방법
    • 제거: 이상치 삭제 (데이터 손실 위험)
    • 대체: 로그 변환, 상·하한값 설정 등
    • 분리: 별도 데이터프레임으로 저장해 분석

📊 이상치 처리 코드 예제

import pandas as pd
from sklearn.preprocessing import StandardScaler

# 1. Z-Score 방식
df = pd.read_csv("p.csv")
df['sw'] = df['Shipping Weight'].str.split().str[0]
df['sw'] = pd.to_numeric(df['sw'], errors='coerce').fillna(0.0).astype(int)

# 표준화
df1 = df[['sw']]
scale_df = StandardScaler().fit_transform(df1)

merge_df = pd.concat([df1, pd.DataFrame(scale_df)], axis=1)
merge_df.columns = ['Shipping Weight', 'zscore']

# 이상치 판별 (-3 ~ 3 범위 밖)
mask = (merge_df['zscore'] < -3) | (merge_df['zscore'] > 3)
strange_df = merge_df[mask]


# IQR 방식
df = pd.read_csv("p.csv")
df['sw'] = df['Shipping Weight'].str.split().str[0]
df['sw'] = pd.to_numeric(df['sw'], errors='coerce').fillna(0.0).astype(int)

df1 = df[['sw']]

# Q1, Q3, IQR 계산
q3 = df1['sw'].quantile(0.75)
q1 = df1['sw'].quantile(0.25)
iqr = q3 - q1

# 이상치 판별 함수
def is_outlier(df1):
    score = df1['sw']
    if score > q3 + 1.5*iqr or score < q1 - 1.5*iqr:
        return '이상치'
    else:
        return '이상치아님'

df1['이상치여부'] = df1.apply(is_outlier, axis=1)

🎯 핵심 메시지

  • 결측치와 이상치 처리는 데이터 분석의 신뢰성을 확보하는 필수 과정
  • 단순히 제거하는 것이 아니라, 데이터 특성과 분석 목적에 맞는 적절한 처리 방법을 선택해야 함
  • 특히 이상치 처리에는 정답이 없으므로, 통계적 기법 + 분석가의 주관적 판단이 조화되어야 함

데이터 EDA는 데이터 분석에 있어서 반드시 행해야 하는 과정이다.

앞서 말했듯이 데이터에는 어쩔 수 없이 오류가 있을 수밖에 없다. 데이터를 저장하는 하드웨어에 문제가 생겨 발생한 오류이든, 데이터를 수집하는 과정에서 실수로 다른 값을 입력하여 저장된 오류이든 간에 말이다.

이 오류들을 바로잡지 않고 데이터 분석을 실행하는 것은 굉장히 위험하다. 잘못된 데이터를 가지고 분석을 실행하면 우리가 원하는 내용물을 받을 수 없을 뿐더러, 자칫하면 원하던 것과는 정반대의 결과물을 볼 수도 있다.

이런 결과물을 가지고 분석을 한다면 당연하게도 올바른 결론을 도출할 수 없다. 따라서 데이터에 있는 오류를 찾아서 이를 처리해야만 한다.

  1. 학습하며 느낀 점
    결측치와 이상치를 처리하는 방법이 굉장히 다양해서 놀랐다. 같은 결측치 제거라도 원하는 방법에 따라 함수에 들어가는 파라미터가 조금씩 바뀌었다.

    SQL은 어느 정도 익숙해지면 쿼리 작성법을 외우게 된다. 하지만 파이썬은 달랐다. 하나를 배우면 그것을 응용하는 다른 것이 다시 나와서 외우기가 굉장히 힘들다. 심지어는 생긴 것도 비슷비슷하다!

    정말 자주 쓰는 함수들은 외우게 되겠지만, 그런 것이 아니라면 구글링을 정말 잘 해야 한다는 뜻이렸다.

    참 헷갈리는 부분이 많지만, 나름의 재미도 함께 느껴지고 있다는 게 신기할 따름이다.

마치며 : 어느덧 11월도 중반을 넘어가고 있다. 벌써 캠프를 시작한 지 한 달이 되다니. 내일이면 각 팀별로 주제를 선정하여 기초 프로젝트를 시작하게 된다. 아직 파이썬은 익숙하지 않아서 걱정이 되기도 한다. 하지만 끝까지 기합으로 버티면서 진행하다 보면 어느 샌가 프로젝트를 완성한 나를 볼 수 있을 것이다.

profile
국문과 전공 데이터 입문자

0개의 댓글