오픈소스기반데이터분석 7강 - 데이터 전처리 (2)
데이터 분석의 품질은 분석 기법보다 먼저 데이터의 품질에서 결정된다. 이번 강의에서는 pandas를 이용해 결측치와 이상치를 탐지하고, 제거·대치·보간 중 적절한 처리 전략을 선택하는 방법을 배운다. 또한 값 변경, 날짜 변환, DataFrame 병합까지 데이터 전처리의 전체 흐름을 코드와 함께 정리한다.
1. 데이터 정제와 결측치 탐지
1.1 데이터 정제의 의미
데이터 정제(data cleansing)는 불완전하거나 부정확한 데이터를 찾아 수정하거나 제거하는 과정이다. 분석 전에 수행하는 대표적인 전처리 작업으로, 결측값·이상값·중복값·오류값 등을 다룬다. 이번 강의의 중심은 값이 기록되지 않은 결측치와 정상 범위를 벗어난 이상치이다.
결측치는 관측값이 존재하지 않는 상태이고, 이상치는 값은 존재하지만 일반적인 범위나 패턴에서 크게 벗어난 상태이다. 두 문제는 탐지 기준과 처리 방법이 서로 다르다.
1.2 pandas의 결측치 표현과 확인
pandas는 주로 NumPy의 NaN으로 결측치를 표현한다. isnull()과 isna()는 각 원소가 결측치인지 검사하여 불리언 값을 반환하며, 두 메서드는 같은 기능을 한다. 반대로 notnull()은 값이 존재하는 원소에 True를 반환한다.
import pandas as pd
df.isna() # 원소별 결측 여부
df.isnull().sum() # 열별 결측치 개수
df.isna().any() # 열별 결측치 존재 여부
df.notnull().sum() # 열별 유효값 개수
불리언 값에서 True는 1로 계산되므로 sum()을 연결하면 결측치 개수를 얻는다. any()는 하나라도 결측치가 있는지 확인할 때 유용하며, 처리를 마친 뒤 결측치가 모두 사라졌는지 재검증하는 데에도 사용할 수 있다.
1.3 결측 패턴의 시각화
결측치 개수만으로는 변수 간 결측 관계나 행별 패턴을 파악하기 어렵다. seaborn의 heatmap()은 결측 여부를 색으로 표현해 변수 사이의 결측 패턴을 보여 주고, missingno 패키지의 matrix()는 데이터 전체의 결측 분포를 행렬 형태로 확인하게 한다.
isna().sum()으로 규모를 수치화하고, 필요할 때 히트맵이나 결측 행렬로 결측이 특정 열·구간에 집중되는지 살펴본다. 결측이 무작위인지 일정한 규칙을 갖는지는 처리 전략 선택에 중요하다.2. 이상치 탐지의 원리
2.1 이상치와 탐지 방법
이상치(outlier)는 다른 관측값과 비교해 지나치게 크거나 작아 일반적인 패턴에서 벗어난 값이다. 입력 오류일 수도 있지만 실제로 발생한 중요한 사건일 수도 있으므로, 탐지 즉시 삭제해서는 안 된다. 값의 생성 배경과 분석 목적을 함께 검토해야 한다.
| 구분 | 대표 방법 | 특징 |
|---|---|---|
| 통계적 탐지 | IQR, Z-점수 | 수치 기준으로 이상 여부를 판정한다. |
| 시각적 탐지 | 상자그림, 산점도 | 분포와 변수 간 관계 속에서 특이한 값을 찾는다. |
상자그림은 사분위수와 수염 밖의 값을 한눈에 보여 주므로 IQR 기준과 잘 연결된다. 산점도는 두 변수의 관계에서 홀로 떨어진 관측치를 찾는 데 효과적이다. 시각화는 후보를 찾는 도구이며, 최종 판단은 통계 기준과 도메인 지식을 함께 사용한다.
2.2 탐지 전에 확인할 사항
- 측정 단위나 입력 형식이 잘못된 값인지 확인한다.
- 정상적으로 가능한 극단값인지 업무 맥락을 살핀다.
- 데이터 분포가 정규분포에 가까운지 확인한다.
- 표본 크기와 이상치 비율이 평균·표준편차에 미치는 영향을 고려한다.
IQR과 Z-점수는 모두 이상치 탐지 방법이지만 전제가 다르다. IQR은 정규분포를 가정하지 않고 극단값의 영향을 비교적 적게 받으며, Z-점수는 평균과 표준편차를 이용하므로 정규분포에 가까울 때 해석력이 높다.
3. IQR을 이용한 이상치 판정
3.1 사분위수와 IQR
IQR(Interquartile Range)은 제3사분위수 Q3에서 제1사분위수 Q1을 뺀 값으로, 데이터의 가운데 50%가 퍼져 있는 범위를 뜻한다.
IQR = Q3 - Q1
하한 = Q1 - 1.5 × IQR
상한 = Q3 + 1.5 × IQR
하한보다 작거나 상한보다 큰 관측값을 이상치 후보로 판정한다. 사분위수는 평균보다 극단값의 영향을 덜 받으므로, 분포가 정규적이지 않거나 이상치가 여러 개 포함된 데이터에 유용하다.
3.2 pandas 구현
scores = [72, 68, 75, 282, 64, 31, 78, 69,
88, 92, 22, 84, 61, -90, 130, 66]
student_id = range(1001, 1017)
df = pd.DataFrame({
'student_id': student_id,
'score': scores
})
q1 = df['score'].quantile(0.25)
q3 = df['score'].quantile(0.75)
iqr = q3 - q1
lower = q1 - 1.5 * iqr
upper = q3 + 1.5 * iqr
outliers = df[(df['score'] < lower) | (df['score'] > upper)]
quantile(0.25)와 quantile(0.75)로 사분위수를 구한 뒤, 두 경계 밖의 행을 불리언 인덱싱으로 추출한다. 이 결과는 삭제 대상이 아니라 먼저 검토할 이상치 후보이다.
4. Z-점수를 이용한 이상치 판정
4.1 Z-점수의 의미
Z-점수는 한 관측값이 평균에서 표준편차의 몇 배만큼 떨어져 있는지를 나타낸다. 절댓값이 클수록 평균에서 멀리 있는 값이다.
Z = (관측값 - 평균) / 표준편차
정규분포를 따르는 자료에서는 Z-점수의 의미가 명확하다. 그러나 평균과 표준편차 자체가 극단값의 영향을 받기 때문에, 이상치가 많거나 분포가 크게 치우친 자료에서는 판정이 왜곡될 수 있다.
4.2 pandas 구현과 비율 계산
mean = df['score'].mean()
std = df['score'].std()
df['z_score'] = (df['score'] - mean) / std
threshold = 2
outliers = df[df['z_score'].abs() > threshold]
outlier_ratio = (df['z_score'].abs() > threshold).mean() * 100
예제에서는 임계값을 2로 설정했으므로 abs(z_score) > 2인 행을 추출한다. 마지막 식은 이상치 여부를 나타내는 불리언 값의 평균에 100을 곱해 전체에서 이상치가 차지하는 백분율을 구한다.
| 비교 항목 | IQR | Z-점수 |
|---|---|---|
| 기준 통계량 | Q1, Q3, 중앙 50% 범위 | 평균, 표준편차 |
| 분포 가정 | 정규분포를 요구하지 않음 | 정규분포에 가까울수록 적합 |
| 극단값 영향 | 비교적 작음 | 평균과 표준편차가 영향을 받음 |
| 대표 판정 | Q1−1.5×IQR 미만 또는 Q3+1.5×IQR 초과 | |Z|가 설정한 임계값 초과 |
5. 문제 데이터의 처리 전략
5.1 제거, 대치, 보간
결측치나 이상치를 발견한 뒤에는 데이터의 특성, 문제 유형, 분석 목적, 데이터 크기를 고려해 처리 방법을 선택한다. 하나의 방법이 언제나 최선인 것은 아니다.
| 전략 | 의미 | 장점 | 주의점 |
|---|---|---|---|
| 제거 | 문제가 있는 행이나 열을 삭제 | 처리가 단순하고 명확함 | 정보 손실과 편향 가능성 |
| 대치 | 적절한 다른 값으로 교체 | 표본 수를 유지함 | 분산이나 관계를 왜곡할 수 있음 |
| 보간 | 주변 관측값의 관계로 값을 추정 | 연속적 흐름을 반영함 | 급격한 변화에서는 오차 가능 |
dropna()는 결측 행이나 열을 제거한다. 데이터가 충분하고 결측 비율이 매우 낮을 때 간편하지만, 작은 데이터나 결측이 특정 집단에 집중된 자료에서는 중요한 정보와 패턴을 잃을 수 있다.
5.2 대치 방법의 선택
| 방법 | 주요 대상 | 선택 기준 |
|---|---|---|
| 평균 대치 | 연속형 변수 | 분포가 대칭적이고 이상치 영향이 작을 때 |
| 중앙값 대치 | 연속형 변수 | 분포가 치우치거나 이상치가 있을 때 |
| 최빈값 대치 | 범주형 변수 | 가장 자주 나타나는 범주로 대체할 때 |
| 특정값 대치 | 모든 자료형 | ‘미상’, 0 등 의미 있는 별도 값을 둘 때 |
| 전방·후방 채우기 | 시계열 | 이전 또는 다음 관측값이 연속성을 대표할 때 |
| kNN 대치 | 다변량 자료 | 유사한 표본과 변수 간 관계를 활용할 때 |
전방 채우기와 후방 채우기는 각각 이전 값과 다음 값을 사용한다. 편리하지만 긴 결측 구간에 동일한 값이 반복될 수 있으므로 시간적 의미가 있는지 확인해야 한다.
5.3 보간 방법의 비교
| 보간법 | 원리와 장점 | 한계 |
|---|---|---|
| 선형 보간 | 앞뒤 값을 직선으로 연결하며 단순하고 빠름 | 변화가 급격하면 부정확할 수 있음 |
| 다항식 보간 | 다항식으로 부드러운 곡선을 근사 | 차수가 높으면 과적합 위험 |
| 스플라인 보간 | 구간별 다항식을 연결해 복잡한 패턴 표현 | 계산량이 비교적 큼 |
| 시간 기반 보간 | 시간 간격을 반영하여 시계열에 적합 | 시간 간격이 불규칙할 때 주의 필요 |
범주형 변수에는 최빈값이나 특정값, 연속형 변수에는 평균·중앙값, 시간 순서가 중요한 값에는 전후 채우기나 보간을 우선 검토한다. 처리 후에는 분포와 변수 관계가 지나치게 바뀌지 않았는지 반드시 확인한다.
6. pandas 값 변경과 날짜 처리
6.1 값 변경 메서드
pandas는 목적에 따라 값을 바꾸는 여러 방법을 제공한다. replace()는 특정 값을 다른 값으로 치환하고, map()은 Series의 각 원소에 함수나 대응표를 적용한다. apply()는 함수 적용에 사용하며, loc는 조건에 맞는 행과 열을 선택해 직접 수정한다. where()는 조건이 참인 값은 유지하고 거짓인 값만 다른 값으로 바꾼다.
data = {
'age': [25, 30, None, 22, 35],
'city': ['Seoul', None, 'Incheon', 'Seoul', 'Daejeon'],
'score': [90, 85, None, 80, 92]
}
df = pd.DataFrame(data)
df['city'] = df['city'].replace('Seoul', '서울')
df['age_str'] = df['age'].map(
lambda x: f"{x}살" if pd.notna(x) else "알수없음"
)
df.loc[df['score'] < 90, 'score'] = 90
df['age_where'] = df['age'].where(df['age'] >= 30, other=0)
마지막 코드에서 나이가 30 이상이면 원래 값을 유지하고, 조건을 만족하지 않거나 결측이라면 0으로 바뀐다. where()의 핵심은 참이면 유지, 거짓이면 교체이다.
6.2 날짜 형식의 표준화
날짜는 국가·조직·문화에 따라 표기 방식이 다르고 윤년과 월별 일수도 고려해야 한다. 문자열 상태로 비교하기보다 pd.to_datetime()으로 날짜형으로 변환한 뒤 dt 접근자를 사용하면 안전하고 일관된 분석이 가능하다.
date_str = ['2025-07-01', '2025-08-01', '2025-09-01']
df_date = pd.DataFrame({'date_str': date_str})
df_date['date'] = pd.to_datetime(df_date['date_str'])
df_date['month'] = df_date['date'].dt.month
df_date['weekday'] = df_date['date'].dt.day_name()
df_date['date_ymd'] = df_date['date'].dt.strftime('%Y년 %m월 %d일')
df_date['date_weekday'] = df_date['date'].dt.strftime('%A, %Y-%m-%d')
dt.month는 월을 숫자로, dt.day_name()은 요일 이름을 반환한다. dt.strftime()은 날짜형 데이터를 원하는 문자열 형식으로 출력한다. 즉, 먼저 날짜형으로 변환하고 필요한 구성 요소를 추출하거나 표시 형식을 바꾸는 순서가 중요하다.
7. 실전 전처리 흐름과 DataFrame 병합
7.1 Store Sales 시계열 데이터 실습
강의에서는 Kaggle의 Store Sales 시계열 데이터를 활용해 전처리 흐름을 연습한다. Kaggle은 데이터 과학 경진대회와 데이터·코드 공유를 지원하는 플랫폼이자 생태계이다.
describe()와 info()로 구조를 확인한다.isnull() 또는 isna()로 탐지하고 데이터 특성에 맞게 interpolate() 등을 적용한다.to_datetime()으로 변환한 뒤 dt 접근자로 월·요일 등 파생 변수를 만든다.merge()하여 여러 DataFrame을 결합한다.7.2 merge와 조인 유형
merge()는 SQL의 JOIN처럼 공통 키를 기준으로 두 DataFrame을 결합한다. 왼쪽 표가 ID 1, 2, 오른쪽 표가 ID 2, 3을 가진다고 가정하면 조인 유형에 따라 포함되는 키가 달라진다.
| 조인 | 포함되는 ID | 의미 |
|---|---|---|
inner | 2 | 양쪽에 모두 존재하는 키만 유지 |
left | 1, 2 | 왼쪽의 모든 키를 유지하며 ID 1의 오른쪽 값은 결측 |
right | 2, 3 | 오른쪽의 모든 키를 유지하며 ID 3의 왼쪽 값은 결측 |
outer | 1, 2, 3 | 양쪽 키의 합집합을 유지하고 짝이 없으면 결측 |
merged_inner = pd.merge(left_df, right_df, on='ID', how='inner')
merged_left = pd.merge(left_df, right_df, on='ID', how='left')
merged_right = pd.merge(left_df, right_df, on='ID', how='right')
merged_outer = pd.merge(left_df, right_df, on='ID', how='outer')
8. 핵심 정리
- 데이터 정제는 결측값, 이상값, 중복값, 오류값 등을 찾아 수정하거나 제거하는 전처리 과정이다.
isnull()과isna()는 결측 여부를 반환하며,sum()·any()와 결합해 규모와 존재 여부를 확인한다.- IQR은
Q3-Q1이며, 일반적으로Q1-1.5×IQR과Q3+1.5×IQR밖을 이상치 후보로 본다. - Z-점수는 평균에서 표준편차 몇 배만큼 떨어졌는지를 나타내며 정규분포에 가까운 자료에 적합하다.
- 결측치와 이상치는 데이터 특성, 분석 목적, 크기를 고려해 제거·대치·보간 중 적절한 방법으로 처리한다.
replace(),map(),apply(),loc,where()는 목적에 맞게 값을 변경하는 도구이다.pd.to_datetime()으로 날짜형을 만들고dt접근자로 월·요일·표시 형식을 다룬다.merge()는 공통 키를 기준으로 DataFrame을 결합하며 inner·left·right·outer 조인의 보존 키가 서로 다르다.
9. 예상문제 20선
1. 데이터 정제에 대한 설명으로 가장 적절한 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
데이터 정제는 결측값·이상값·중복값·오류값 등을 탐지해 수정 또는 제거하는 대표적인 데이터 전처리 과정이다.
2. pandas에서 결측치를 나타내는 대표적인 값은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
pandas는 주로 NumPy의 NaN을 이용해 값이 누락된 상태를 표현한다.
3. DataFrame의 열별 결측치 개수를 구하는 코드로 알맞은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①isna()가 반환한 불리언 값에서 True를 1로 합산하면 각 열의 결측치 개수를 구할 수 있다.
4. notnull()의 동작으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③notnull()은 isnull()의 반대 동작으로, 결측이 아닌 원소를 True로 표시한다.
5. 결측 패턴을 시각적으로 확인하는 도구의 연결로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
히트맵은 결측 여부를 색으로, missingno의 matrix는 전체 결측 분포를 행렬 형태로 보여 준다.
6. 강의에서 제시한 이상치 탐지 방법의 조합으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
IQR과 Z-점수는 통계적 탐지, 상자그림과 산점도는 시각적 탐지에 해당한다.
7. IQR 이상치 판정의 상한을 구하는 식은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
IQR은 Q3−Q1이며, 일반적인 상한은 Q3+1.5×IQR이다.
8. IQR 방법이 특히 유용한 상황은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
IQR은 사분위수를 사용하므로 정규분포를 요구하지 않고 극단값의 영향도 비교적 적다.
9. Z-점수에 대한 설명으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
Z=(관측값−평균)/표준편차이며, 평균에서 떨어진 상대적 거리를 표준편차 단위로 표현한다.
10. 임계값이 2일 때 Z-점수 이상치 후보를 추출하는 조건은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
평균보다 큰 방향과 작은 방향을 모두 검사해야 하므로 Z-점수의 절댓값이 임계값보다 큰지 판정한다.
11. 결측치가 있는 행이나 열을 제거할 때 가장 주의해야 할 점은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
제거는 단순하지만 작은 데이터나 규칙적인 결측 패턴에서 중요한 정보와 특정 집단의 관측치를 잃을 수 있다.
12. 대치 방법과 주요 대상의 연결로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
중앙값은 이상치나 치우친 분포의 연속형 변수에, 최빈값은 범주형 변수에 주로 사용한다.
13. 전방 채우기와 후방 채우기를 우선 검토할 수 있는 데이터는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
이전 또는 다음 관측값을 사용하는 방식이므로 시간적 연속성이 의미 있는 시계열에 적합하다.
14. 선형 보간에 대한 설명으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
선형 보간은 계산이 간단하지만 실제 데이터가 빠르게 변하거나 곡선 패턴이면 오차가 커질 수 있다.
15. 보간 방법의 특징으로 옳지 않은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
스플라인은 복잡한 패턴을 유연하게 표현하지만 선형 보간보다 계산량이 클 수 있다.
16. pandas 값 변경 기능의 설명으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③loc에 행 조건과 열 이름을 지정하면 조건부 값을 직접 수정할 수 있다.
17. Series.where(condition, other=0)의 동작으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③where()는 조건을 만족하는 원래 값은 보존하고, 만족하지 않는 위치를 other로 대체한다.
18. 문자열 날짜에서 월과 요일을 추출하는 올바른 순서는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
문자열을 날짜형으로 표준화한 다음 dt.month, dt.day_name() 등으로 구성 요소를 추출한다.
19. 왼쪽 표의 ID가 1, 2이고 오른쪽 표의 ID가 2, 3일 때 조인 결과로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
outer join은 양쪽 키의 합집합을 유지하므로 1, 2, 3이 모두 포함되고 대응 값이 없으면 결측치가 생긴다.
20. Store Sales 데이터 전처리 실습의 흐름으로 가장 적절한 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
먼저 데이터의 구조와 상태를 측정한 뒤 문제를 처리하고, 날짜 파생 변수 생성과 공통 키 기반 병합으로 분석용 데이터를 완성한다.
댓글
댓글 쓰기