기본 콘텐츠로 건너뛰기

방송대 오픈소스기반데이터분석 7강: 결측치·이상치 판단과 데이터 통합

오픈소스기반데이터분석 7강 - 데이터 전처리 (2)

방송대 오픈소스기반데이터분석 7강: 결측치·이상치 판단과 데이터 통합

결측값과 이상한 숫자를 발견했다고 바로 삭제하면 중요한 신호까지 사라질 수 있다. 데이터 정제는 ‘지우는 기술’이 아니라 문제의 원인을 확인하고 분석 목적에 맞는 조치를 선택하는 판단 과정이다. 결측치 탐지, IQR·Z-score 비교, 대치·보간, 값과 날짜 변환, DataFrame 병합을 하나의 정제 사례로 연결한다.

이상한 값을 만났을 때 첫 질문은 삭제 여부가 아니다

데이터 정제(data cleansing)는 결측치, 이상치, 중복값, 오류값처럼 분석을 방해할 수 있는 불완전하거나 부정확한 데이터를 찾아 수정·대체·제거하는 과정이다. 여기서 결측치는 값이 존재하지 않는 상태이고, 이상치는 일반적인 범위에서 멀리 떨어진 특이한 값이다.

하지만 “분석을 방해할 수 있다”와 “반드시 없애야 한다”는 다르다. 상품 가격 -10은 입력 오류일 수도 있고 환불 거래일 수도 있다. 평소보다 10배 큰 전력 사용량은 센서 오류일 수도 있고 실제 사고 징후일 수도 있다. 통계적 탐지 결과는 검토할 후보를 만들 뿐, 처리 결정을 자동으로 내려 주지 않는다.

정제 의사결정 5단계: ① 문제를 탐지한다. ② 값이 생긴 원인과 업무 의미를 확인한다. ③ 분석 목적에 미치는 영향을 평가한다. ④ 유지·수정·대치·보간·제거 중 조치를 선택한다. ⑤ 처리 전후의 행 수·분포·결과 차이와 근거를 기록한다.

문제 유형확인할 원인가능한 조치
결측치점수 없음미응시, 수집 실패, 미입력유지, 대치, 보간, 행·열 제거
이상치점수 282, -90단위 오류, 입력 오류, 실제 특이 사례원자료 확인, 수정, 별도 표시, 제한, 제거
오류값도시명 ‘Seol’오타, 코드 체계 불일치표준값으로 치환
중복값같은 거래 두 번재전송, 실제 반복 거래키와 시각을 검토한 뒤 중복 제거

결측치 탐지는 값의 개수와 위치를 함께 본다

pandas는 수치형의 NaN, 날짜형의 NaT, 객체 안의 None 등 여러 결측 표현을 다룬다. isna()isnull()은 같은 역할을 하며 각 셀이 결측이면 True인 불리언 마스크를 반환한다. notna()notnull()은 반대 마스크다.

import pandas as pd

df = pd.DataFrame({
    "age": [25, 30, None, 22, 35],
    "city": ["Seoul", None, "Incheon", "Seoul", "Daejeon"],
    "score": [90, 85, None, 80, 92],
})

print(df.isna().sum())
print(df.isna().any())
print(df.isna().to_numpy().any())

df.isna().sum()은 열별 결측치 개수를, df.isna().any()는 열별 포함 여부를 보여 준다. 마지막 식은 전체 DataFrame에 결측치가 하나라도 있는지를 단일 참·거짓 값으로 축약한다. 처리 후 같은 검사를 반복하면 목표로 한 결측치가 남았는지 검산할 수 있다.

빈 문자열 주의: ""나 공백 문자열은 기본적으로 결측치로 판정되지 않는다. 원자료에서 공백, "N/A", "미입력"을 결측 의미로 사용했다면 불러오기 옵션이나 replace()로 표준 결측값으로 통일해야 한다.

히트맵이나 missingno의 매트릭스는 결측 위치를 행·열 패턴으로 보여 준다. 특정 기간에 여러 센서가 동시에 비었다면 개별 값의 우연한 누락보다 수집 시스템 장애를 의심할 수 있다. 시각화는 개수만으로 보이지 않는 공동 누락 패턴을 찾는 보조 수단이다.

IQR은 분포의 가운데 절반을 기준으로 경계를 만든다

IQR(Interquartile Range, 사분위범위)은 제3사분위수 Q3에서 제1사분위수 Q1을 뺀 값이다. 데이터의 가운데 50%가 퍼진 정도를 나타내며, 평균과 표준편차보다 극단값의 영향을 덜 받는다.

강의의 점수 데이터로 직접 계산해 보자.

scores = pd.Series([
    72, 68, 75, 282, 64, 31, 78, 69,
    88, 92, 22, 84, 61, -90, 130, 66,
])

q1 = scores.quantile(0.25)
q3 = scores.quantile(0.75)
iqr = q3 - q1
lower = q1 - 1.5 * iqr
upper = q3 + 1.5 * iqr
outliers_iqr = scores[(scores < lower) | (scores > upper)]

pandas의 기본 선형 보간 방식으로 Q1=63.25, Q3=85.00이고, IQR=21.75다. 따라서 하한은 63.25-1.5×21.75=30.625, 상한은 85+1.5×21.75=117.625다. 경계 밖의 값은 282, 22, -90, 130 네 개다.

  1. 사분위수 Q1, Q3을 구한다.
  2. IQR=Q3-Q1을 계산한다.
  3. 하한 Q1-1.5×IQR과 상한 Q3+1.5×IQR을 만든다.
  4. 경계보다 작거나 큰 값을 후보로 표시한다.
  5. 후보의 원자료와 의미를 확인한 뒤 처리 여부를 정한다.

Z-score는 평균에서 떨어진 거리를 표준편차 단위로 바꾼다

Z-score는 각 값에서 평균을 빼고 표준편차로 나눈 값이다. 절댓값이 클수록 평균에서 멀리 떨어져 있다.

z=(x-평균)/표준편차

pandas의 Series.std()는 기본적으로 N-1로 나눈 표본 표준편차를 사용한다. 강의 데이터의 평균은 74.5, 표본 표준편차는 약 72.517이다.

mean = scores.mean()
std = scores.std()
z_score = (scores - mean) / std
outliers_z = scores[z_score.abs() > 2]

임계값을 2로 놓으면 282의 Z-score는 약 2.861, -90은 약 -2.268이므로 두 값만 후보가 된다. IQR이 표시한 22130은 이 기준에서는 제외된다.

기준IQRZ-score
중심과 퍼짐사분위수와 가운데 50%평균과 표준편차
극단값 영향상대적으로 작음평균·표준편차가 함께 흔들릴 수 있음
적합한 상황비대칭이거나 극단값이 있는 분포정규분포에 가까운 자료
이 예제의 후보282, 22, -90, 130임계값 2에서 282, -90

불일치 해석: 두 방법의 결과가 다르면 한쪽이 틀렸다고 결론내리지 않는다. 분포 가정, 표본 크기, 임계값과 분석 목적이 다르므로 히스토그램·박스플롯·업무 범위를 함께 확인한다.

결측치 처리는 데이터가 빠진 이유에 따라 달라진다

결측 행이나 열을 제거하는 dropna()는 간단하지만 정보 손실이 생긴다. 표본이 충분히 크고 결측 비율이 작으며 누락이 분석 결과를 체계적으로 왜곡하지 않을 때만 신중하게 사용한다. 특정 집단에서 응답이 더 자주 빠졌다면 그 행을 삭제하는 순간 편향이 커질 수 있다.

전략적합한 상황주의점
평균 대치극단값이 적은 연속형 변수분산을 줄이고 분포를 중앙에 몰 수 있음
중앙값 대치치우친 연속형 변수변수 간 관계를 보존하지 못할 수 있음
최빈값 대치범주형 변수가장 흔한 범주의 비율을 과장할 수 있음
특정값 대치‘미상’ 자체가 의미 있는 경우실제 값과 구분되는 표식을 선택
전방·후방 채우기순서가 있는 시계열·상태 자료정렬 확인과 연속 결측 길이 제한 필요
k-최근접 이웃 대치다변량 관계가 있는 자료거리 척도·변수 스케일과 계산비용 고려
cleaned = df.copy()
cleaned["age"] = cleaned["age"].fillna(cleaned["age"].median())
cleaned["city"] = cleaned["city"].fillna("미상")
cleaned["score"] = cleaned["score"].fillna(cleaned["score"].mean())

assert not cleaned[["age", "city", "score"]].isna().any().any()

모든 열을 같은 값으로 채우지 않고 변수의 의미와 분포에 맞춰 전략을 나눴다. 실제 분석에서는 대치 전 결측 여부를 별도 불리언 열로 남기면 “원래 관측값”과 “추정·대치값”을 구분할 수 있다.

보간은 관측 순서와 거리의 의미가 있을 때 사용한다

보간(interpolation)은 결측값 전후의 관측 관계를 이용해 중간 값을 추정한다. 선형 보간은 두 점을 직선으로 연결해 간단하고 빠르지만 급격한 변화에는 맞지 않을 수 있다. 다항식·스플라인 보간은 곡선을 표현할 수 있지만 과적합과 계산비용을 주의해야 한다.

series = pd.Series([10.0, None, None, 16.0])
print(series.interpolate())
# 10.0, 12.0, 14.0, 16.0

두 결측값은 앞의 10과 뒤의 16 사이를 같은 간격으로 나눠 12와 14가 된다. 하지만 행 순서가 시간이나 공간의 연속성을 뜻하지 않는 학생 명단이라면 이런 계산은 근거가 없다.

시간 간격이 일정하지 않은 시계열은 날짜·시간을 인덱스로 만들고 시간 기반 보간을 고려한다. 먼저 시간순 정렬, 중복 시각, 시간대와 측정 간격을 확인해야 한다. 전방 채우기도 마지막 상태가 다음 관측까지 유지된다는 가정이 있을 때만 타당하다.

보간 경계: 데이터의 줄 순서만으로 가까운 관측이라고 가정하지 않는다. 시간·거리·순서의 의미와 변화가 매끄럽다는 가정이 설명될 때 보간을 선택한다.

값 변경 도구는 바꾸려는 범위와 규칙으로 구분한다

pandas에는 비슷해 보이는 값 변경 도구가 여럿 있다. 도구 이름보다 “정확히 어떤 범위에 어떤 규칙을 적용하는가”를 기준으로 고르면 혼동이 줄어든다.

도구주요 용도
replace()알려진 값이나 패턴을 다른 값으로 치환"Seol""Seoul"로 교정
Series.map()한 Series의 각 값에 함수·매핑 적용도시 코드를 도시명으로 변환
apply()Series 값 또는 DataFrame의 행·열에 함수 적용여러 열을 사용한 파생값 계산
loc조건으로 행·열을 선택해 대입음수 점수를 결측 후보로 표시
where()조건이 참인 값은 유지하고 거짓인 값은 교체허용 범위 밖 값을 NaN으로 변경
df["city"] = df["city"].replace("Seol", "Seoul")
df["age_label"] = df["age"].map(
    lambda x: f"{x:.0f}세" if pd.notna(x) else "미상"
)
df.loc[df["score"] < 0, "score"] = pd.NA
df["score_capped"] = df["score"].where(df["score"] <= 100, 100)

where()는 조건이 참인 값을 남긴다는 방향을 기억한다. 위 코드는 100 이하를 유지하고 그보다 큰 값을 100으로 바꾼다. 그러나 실제 점수 282가 단위 오류인지 다른 척도인지 확인하지 않고 상한을 씌우면 잘못을 숨길 수 있으므로, 예시는 도구 동작을 보여 주는 것이지 자동 처리 권고가 아니다.

날짜는 문자열을 변환한 뒤 속성을 추출한다

날짜 문자열은 국가와 조직에 따라 표기가 다르고, 윤년과 월별 일수도 있어 문자열 자르기만으로 안전하게 처리하기 어렵다. 먼저 pd.to_datetime()으로 날짜·시간 자료형으로 변환한 뒤 dt 접근자로 연·월·일·요일을 추출한다.

dates = pd.DataFrame({
    "date_text": ["2025-07-01", "2025-08-01", "잘못된 날짜"],
})

dates["date"] = pd.to_datetime(dates["date_text"], errors="coerce")
dates["month"] = dates["date"].dt.month
dates["weekday"] = dates["date"].dt.day_name()
dates["date_ymd"] = dates["date"].dt.strftime("%Y년 %m월 %d일")

errors="coerce"는 해석할 수 없는 문자열을 날짜 결측값 NaT로 바꾼다. 오류를 조용히 없애는 옵션이 아니라, 실패 위치를 결측 마스크로 모아 검토할 수 있게 하는 선택이다. 변환 후 dates["date"].isna()로 실패 행을 확인해야 한다.

날짜 검증 순서: 원문 보존 → 형식·로캘 확인 → to_datetime() 변환 → 실패한 NaT 점검 → 시간순 정렬과 중복 확인 → 필요한 속성 추출.

merge는 조인 방식뿐 아니라 키의 품질까지 확인해야 한다

merge()는 SQL의 JOIN과 비슷하게 두 DataFrame을 키 기준으로 결합한다. 왼쪽 표가 ID 1, 2, 오른쪽 표가 ID 2, 3이라면 조인 방식에 따라 남는 키가 달라진다.

how남는 키이 예제의 의미
inner교집합 2양쪽에 모두 있는 행
outer합집합 1, 2, 3한쪽에만 있는 행도 결측값과 함께 유지
left왼쪽의 1, 2왼쪽 행을 모두 보존
right오른쪽의 2, 3오른쪽 행을 모두 보존
left = pd.DataFrame({"ID": [1, 2], "X": ["a1", "a2"]})
right = pd.DataFrame({"ID": [2, 3], "Y": ["b1", "b2"]})

outer = left.merge(
    right,
    on="ID",
    how="outer",
    indicator=True,
    validate="one_to_one",
)

indicator=True는 행이 왼쪽만, 오른쪽만, 양쪽 모두에서 왔는지 표시한다. validate="one_to_one"는 양쪽 키가 유일하다는 기대를 검사한다. 키가 중복된 상태에서 다대다 병합을 하면 행 수가 곱처럼 늘어날 수 있으므로 병합 전후 행 수와 키 중복을 반드시 확인한다.

SQL과 다른 경계: pandas의 병합에서는 양쪽 키가 모두 결측값이면 서로 매칭될 수 있다. 결측 키가 ‘같은 대상을 뜻한다’는 보장이 없으므로 병합 전에 결측 키를 별도로 검토한다.

정제 기록표가 재현성과 책임을 만든다

Kaggle의 판매 시계열처럼 여러 파일을 다루는 실습에서는 로드·측정, 결측치 처리, 이상치 처리, 날짜 변환, 데이터 통합의 순서가 반복된다. 각 단계에서 코드를 실행하는 것만큼 왜 그 조치를 골랐는지 기록하는 일이 중요하다.

기록 항목예시
문제와 위치score 열 16건 중 IQR 후보 4건
탐지 기준Q1-1.5×IQR 미만 또는 Q3+1.5×IQR 초과
원인 확인원자료·단위·허용 범위와 대조
선택한 조치원본 열 보존, 검토 상태 열 추가, 확정 오류만 수정
검산행 수, 결측 수, 분포, 병합 키 유일성 비교

원본을 덮어쓰기보다 정제본을 새 객체나 새 파일로 만들고, 처리 전후 통계를 비교한다. info()는 열·자료형·결측 개요를, describe()는 기술통계를 파악하는 출발점이 된다. 자동화된 정제 규칙도 표본 행을 직접 검토해 의도한 값만 바뀌는지 확인한다.

핵심 개념 정리

  • 결측치와 이상치는 탐지 결과이며, 원인과 분석 목적을 확인한 뒤 처리한다.
  • isna()는 셀별 결측 마스크를 만들고 sum()·any()로 개수와 포함 여부를 요약한다.
  • IQR은 사분위수에, Z-score는 평균과 표준편차에 기반하므로 같은 자료에서도 후보가 다를 수 있다.
  • 제거·대치·보간은 각각 다른 가정과 정보 손실을 가지며 변수의 의미와 누락 원인을 고려한다.
  • replace, map, apply, loc, where는 적용 범위와 조건 유지 방향이 다르다.
  • 날짜 변환 실패와 병합 키의 중복·결측은 별도로 검증해야 한다.

정제의 전체 사고 순서: 구조와 분포를 측정하고 문제 위치를 표시한 뒤, 업무 의미와 발생 원인을 확인한다. 처리 방법의 가정을 설명하고 원본을 보존한 채 적용하며, 처리 전후 통계와 병합 행 수를 검산한다. 탐지·판단·조치·검증 기록이 남아야 같은 결과를 재현할 수 있다.

예상문제 10선

1. 데이터 정제에 대한 설명으로 가장 적절한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②

  • ① 오답: 이상치 후보에는 실제 중요한 사건이 포함될 수 있어 자동 삭제하면 안 된다.
  • ② 정답: 탐지와 함께 원인 확인, 조치 선택, 검증까지 포함한 설명이다.
  • ③ 오답: 자료형을 문자열로 바꾸면 수치 연산과 오류 검증이 더 어려워진다.
  • ④ 오답: 시각화 장식이 아니라 분석 전 데이터 품질을 다루는 과정이다.

2. Q1=63.25, Q3=85.00일 때 1.5×IQR 기준의 상한은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③

  • ① 오답: Q3에 IQR의 절반만 더한 값이다.
  • ② 오답: Q3+IQR까지만 계산해 1.5배를 반영하지 않았다.
  • ③ 정답: IQR=21.75이고 85+1.5×21.75=117.625다.
  • ④ 오답: Q1Q3의 역할 및 배수를 잘못 결합한 값이다.

3. IQR과 Z-score를 올바르게 비교한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①

  • ① 정답: 두 방법의 중심과 퍼짐을 정의하는 통계량 차이를 정확히 설명한다.
  • ② 오답: 분포와 임계값에 따라 후보가 달라지며 강의 데이터에서도 결과가 다르다.
  • ③ 오답: 두 방법이 사용하는 통계량을 서로 잘못 배정했다.
  • ④ 오답: Z-score는 수치가 평균에서 떨어진 거리를 표준편차 단위로 나타낸다.

4. 결측치 탐지에 대한 설명 중 틀린 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: 같은 크기의 결측 마스크를 만든다는 올바른 설명이다.
  • ② 오답: 참이 1로 합산되어 각 열의 결측 개수를 계산할 수 있다.
  • ③ 오답: notna()isna()의 반대 마스크다.
  • ④ 정답: 빈 문자열은 기본 결측값이 아니므로 별도 표준화가 필요하다.

5. 치우친 소득 데이터의 일부 결측치를 단일 대표값으로 대치하려 할 때 우선 고려할 값은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②

  • ① 오답: 열 이름은 수치 분포를 대표하지 않는다.
  • ② 정답: 중앙값은 치우친 연속형 자료에서 극단값의 영향을 평균보다 덜 받는다.
  • ③ 오답: 순서 관계와 상태 유지 가정이 없으면 마지막 값 대치는 근거가 없다.
  • ④ 오답: 소득은 연속형이므로 문자열을 넣으면 자료형과 계산에 문제가 생긴다.

6. pd.Series([10.0, None, None, 16.0]).interpolate()의 두 결측값은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: 앞 값을 복사하는 전방 채우기의 결과이며 선형 보간이 아니다.
  • ② 오답: 두 위치가 서로 다른 간격에 있으므로 같은 중간값을 받지 않는다.
  • ③ 오답: 값의 증가 방향을 거꾸로 배정했다.
  • ④ 정답: 10에서 16까지 세 구간의 증가량 2를 차례로 적용한다.

7. where()의 동작을 가장 정확하게 설명한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③

  • ① 오답: 행 삭제가 아니라 값의 조건부 유지·교체를 수행한다.
  • ② 오답: 키 기반 결합은 merge()의 역할이다.
  • ③ 정답: 조건을 만족하는 원래 값을 보존한다는 방향이 핵심이다.
  • ④ 오답: 날짜 변환에는 pd.to_datetime()을 사용한다.

8. 날짜 문자열을 분석용 날짜로 정제하는 순서로 가장 적절한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①

  • ① 정답: 복구 가능한 원문을 남기고 변환 실패를 확인한 뒤 파생 속성을 만든다.
  • ② 오답: 변환 전에 요일을 안정적으로 계산할 수 없고 원문을 먼저 지우면 검토가 어렵다.
  • ③ 오답: 실패 원인을 확인하지 않은 삭제와 수동 입력은 재현성을 해친다.
  • ④ 오답: 병합과 이상치 통계는 날짜 자료형 변환의 필수 선행 단계가 아니다.

9. 키가 중복된 두 DataFrame을 병합할 때 생길 수 있는 문제는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: 키 중복 자체가 모든 수치형 자료형을 바꾸지는 않는다.
  • ② 오답: 병합은 날짜값을 현재 시각으로 자동 대체하지 않는다.
  • ③ 오답: 겹치는 비키 열에는 접미사가 붙을 수 있지만 열 전체를 삭제하지 않는다.
  • ④ 정답: 같은 키의 왼쪽 행과 오른쪽 행이 여러 조합으로 매칭되므로 행이 증폭될 수 있다.

10. 점수 열에서 IQR과 Z-score의 이상치 후보가 다를 때 가장 적절한 행동은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②

  • ① 오답: 탐지 후보 수는 삭제 기준이 아니며 실제 특이 사건을 잃을 수 있다.
  • ② 정답: 방법의 가정과 데이터 맥락을 연결해 후보별 조치를 판단하는 절차다.
  • ③ 오답: 결과 차이는 각 방법의 민감도와 가정을 검토할 단서이지 폐기 사유가 아니다.
  • ④ 오답: 원래 분포와 개별 차이를 없애 분석 가치를 훼손한다.

참고 자료와 작성 기준

이 글은 해당 차시 강의자료를 바탕으로 학습 목적에 맞게 재구성한 비공식 학습자료입니다. 개념 관계, 예제와 문제 해설은 학습자의 이해를 돕도록 구성하고 검토했습니다.

  • 작성·편집: 올에이클래스 학습연구팀
  • 주요 근거: 한국방송통신대학교 컴퓨터과학과 「오픈소스 기반 데이터분석」 제7강 강의자료(2025)
  • 보충 자료: pandas 공식 API 문서의 isna, Series.std, merge(2026-08-30 확인)
  • 편집 원칙: 올에이클래스 편집 정책
  • 최종 내용 검토: 2026-08-30

댓글