728x90
실무 데이터는 항상 ‘깨끗하지 않다’.
CSV로 가져온 고객 데이터, DB에서 추출한 로그 데이터, API로 받은 응답 등…
결측치(NaN)는 생각보다 자주, 그리고 다양한 형태로 등장한다.
import pandas as pd
import numpy as np
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eva'],
'age': [25, np.nan, 35, 40, np.nan],
'score': [88, 92, np.nan, 70, 91]
})
결측치 확인
컬럼별 결측 여부 확인
df.isnull()
→ 모든 셀에 대해 True/False 마스크 반환
결측치 개수 요약
df.isnull().sum()
→ 각 컬럼별 NaN 개수
전체 결측치가 있는 행만 보기
df[df.isnull().any(axis=1)]
결측치 제거 – dropna()
결측치가 포함된 행 제거
df.dropna()
→ 한 행이라도 NaN이 있으면 해당 행 전체 제거
특정 컬럼 기준으로만 결측치 제거
df.dropna(subset=['score'])
→ score가 NaN인 행만 제거
모두 NaN인 행만 제거
df.dropna(how='all')
결측치 대체 – fillna()
숫자형 컬럼: 특정 값으로 채우기
df['age'].fillna(30) # 평균 나이로 대체하는 것도 가능
전체 DataFrame에 일괄 적용
df.fillna(0)
평균값으로 대체 (실무에서 가장 자주 씀)
df['score'].fillna(df['score'].mean(), inplace=True)
결측치 존재 여부 확인 – .isnull().any()
df.isnull().any().any() # True → 하나라도 NaN이 있다면 True
→ 데이터 전처리 완료 전, sanity check용으로 유용함
결측치 위치 찾기 (디버깅용)
df[df['age'].isnull()]
→ age가 결측인 행만 추출해서 원인 파악 가능
예제: 평균값으로 age 대체 + score 결측 행 제거
df['age'].fillna(df['age'].mean(), inplace=True)
df = df.dropna(subset=['score'])
주의사항
- 모든 NaN을 0으로 대체하지 말 것
→ 의미 없는 0은 오히려 왜곡된 분석을 유발함 - 범주형 데이터는 mode(최빈값)로 대체하거나 따로 분리 처리
→ 예: 성별 컬럼에 NaN이 있으면 'unknown' 등으로 구분 - 수정한 내용은 inplace 또는 재할당으로 저장
→ df = df.fillna(...) 혹은 inplace=True 꼭 확인할 것
결측치는 피할 수 없는 존재다.
하지만 그걸 제대로 처리하지 않으면 전체 분석 결과가 흔들릴 수 있다.
Pandas의 isnull, dropna, fillna는 간단하지만 강력한 도구이니,
데이터 분석 전에 항상 결측 여부부터 점검하고 넘어가야한다.
728x90
반응형
'python > Pandas | Numpy' 카테고리의 다른 글
[Pandas] 조건 조합 필터링 및 추출 (0) | 2025.04.24 |
---|---|
[Pandas] 데이터 타입 확인 및 변환 – dtypes, astype() (0) | 2025.04.24 |
[Pandas] 정렬과 순위 매기기 – sort_values, rank (0) | 2025.04.24 |
[Pandas] Boolean Indexing (조건 필터링) (0) | 2025.04.24 |
[Pandas] 인덱싱 – loc vs iloc (0) | 2025.04.24 |