데이터가 비어 있거나 유효하지 않은 상태
NaN (Not a Number)
Null
' ', 'NA', '-', '없음' 같은 텍스트로 된 결측치
na_values=
data.csv 파일을 읽어오면서 특정한 문자열('-', '없음', 'N/A')을 결측값(NA, NaN) 으로 처리하는 기능
na_values=['-', '없음', 'N/A']
na_values 옵션을 사용하여 특정한 값들을 결측값(NaN) 으로 변환
리스트에 있는 ['-', '없음', 'N/A'] 값들은 모두 NaN(결측값) 으로 처리
df = pd.read_csv('data.csv', na_values=['-', '없음', 'N/A'])
na_values를 활용하는 이유?
결측값을 일관되게 처리할 수 있음
CSV 데이터에서 결측값을 표현하는 방식이 제각각
ex) '-', '없음', 'N/A', ''(빈 문자열) 등이 있을 수 있음.
na_values를 사용하면 이를 모두 NaN으로 변환가능.
여러 개의 na_values 설정
na_values에는 리스트뿐만 아니라 딕셔너리도 사용가능
df = pd.read_csv('data.csv', na_values={'나이': ['없음', '-'], '점수': ['N/A']})
'나이' 열에서는 ['없음', '-']을 NaN으로 변환
'점수' 열에서는 'N/A'만 NaN으로 변환
특정 열에만 적용하고 싶을 때 유용
df.isnull() # True/False 형태로 표시
df.isnull().sum() # 컬럼별 결측치 개수
df['col'].isnull().sum() # 특정 컬럼의 결측치 개수
df.info() # 전체 결측치 요약
import seaborn as sns
import matplotlib.pyplot as plt
sns.heatmap(df.isnull(), cbar=False) # 결측치 위치 시각화
plt.show()
| 처리 방법 | 설명 | 예시 코드 |
|---|---|---|
| 삭제 | 행 또는 열 제거 | df.dropna() |
| 채우기 | 평균, 최빈값 등으로 대체 | df.fillna(df['col'].mean()) |
| 고정값 | 0, '없음' 등으로 채우기 | df.fillna(0) |
| 예측 기반 채우기 | 머신러닝 모델로 결측값 예측 |
df.dropna() # 결측치가 있는 행 삭제
df.dropna(axis=1) # 결측치가 있는 열 삭제
df.dropna(subset=['col1', 'col2']) # 특정 열 기준으로만 삭제
df['col'].fillna(df['col'].mean(), inplace=True) # 평균
df['col'].fillna(df['col'].median(), inplace=True) # 중앙값
df['col'].fillna(df['col'].mode()[0], inplace=True) # 최빈값
df['col'] = df.groupby('group_col')['col'].transform(lambda x: x.fillna(x.mean()))
group_col을 기준으로 그룹을 나누고, 각 그룹 내에서 col 열의 결측값(NA)을 해당 그룹의 평균값으로 채움
df['col'] = df.groupby('group_col')['col'].transform(lambda x: x.fillna(x.mean()))
df.groupby('group_col')
groupby('group_col')는 group_col을 기준으로 데이터를 그룹화
ex) group_col이 'A', 'B', 'C' 3가지 값만 가진다고 가정하면, df는 3개의 그룹으로 나뉩니다.
['col']
그룹화한 후 col 열만 선택 (col 열의 데이터를 그룹별로 다루기 위해)
.transform(lambda x: x.fillna(x.mean()))
transform()
그룹별로 계산한 값을 원래 데이터프레임의 크기에 맞게 반환
lambda x: x.fillna(x.mean())
col의 특정 그룹 내 데이터 x.mean()을 이용하여 계산
그룹 내 col컬럼의 평균을 구함
fillna(x.mean())를 사용하여 x의 결측값(NA)을 그룹 내 평균으로 채움
| 상황 | 추천 처리 방법 |
|---|---|
| 결측치가 전체의 5% 미만 | 평균/최빈값/고정값으로 채우기 |
| 특정 열에만 결측치 집중 | 해당 열만 삭제 or 채우기 |
| 결측치가 너무 많다 (30% 이상) | 열 자체를 삭제 고려 |
| 범주형 변수에 결측치 | '없음', '기타' 등으로 채우기 |
| 수치형 변수에 결측치 | 평균, 중앙값, 예측모델 등 활용 |
결측치가 어디에, 몇 개 있는지 확인했는가?
삭제 vs 채우기 전략을 명확히 선택했는가?
채울 때 기준(평균, 중앙값 등)은 적절한가?
범주형 vs 수치형을 구분해서 처리했는가?
| 실수 | 설명 | 해결 방법 |
|---|---|---|
| 결측치가 문자열로 있음 | 예: '-', 'N/A' | na_values로 지정해서 불러오기 |
| 수치형에 문자열이 섞여 있음 | '70kg' 등 | 정규표현식, 문자열 처리 후 astype() |
| 채운 값이 데이터 분포를 왜곡함 | 평균으로만 다 채움 | 분포 확인 후 적절한 통계값으로 대체 |
| inplace=True 빼먹음 | fillna 후 반영이 안 됨 | inplace=True 쓰거나 다시 할당하기 |