안녕하세요? mangoseed3434입니다.
이번에는 데이터에 포함된 오류를 찾고 정제하는 방법에 대해 학습했어요.
오늘도 'Do it! 쉽게 배우는 파이썬 데이터 분석'에 수록된 문제를 실습하면서 포스팅을 작성합니다.

데이터의 오류에는 크게 3종류가 있어요.
데이터의 오류
1. 결측치 (Missing Value) : 누락된 값, 비어있는 값
2. 이상치 (Anomaly) : 정상 범위에서 벗어난 값 (성별이 1, 2가 아닌 3인 경우)
3. 극단치 (Outlier) : 극단적으로 크거나 작은 값 (몸무게가 1,000kg 이상인 경우)
데이터에 오류가 있으면 분석 결과가 왜곡되는 문제가 발생해요.
그래서 데이터를 분석하기 전에는 결측치가 있는지 확인하고 제거하는 정제 과정 후에 데이터 분석을 해야 합니다.
학부 시절, Rhodomine B의 분자흡광계수를 분석할 때, 흡광도가 낮았던 데이터는 분석에서 제외한 기억이 나네요.

예시로 3행 1열과 5행 2열에 NaN으로 결측치가 있는 데이터 프레임을 만들었어요.
데이터 프레임은 pandas.DataFrame({'변수명1' : [변수값]}) 형식!
[ 대괄호 ], { 중괄호}, (소괄호) 신경쓰기!!

pd.isna(데이터프레임)을 입력하면, 데이터프레임에 결측치가 있는지 파악할 수 있어요.
결측치가 있으면 True가 출력되고, 결측치가 없으면 False가 출력되더라고요.
동일하게, 3행 1열과 5행 2열에 True가 출력됬어요.

동시에, pd.isna()에 sum()을 적용하면, 데이터프레임 내 결측치의 갯수를 빠르게 파악할 수 있더라고요.
저는,
head(), info(), describe(include = 'all')로 데이터프레임을 개략적으로 파악한 후,
pd.isna()와 pd.isna().sum()으로 결측치를 파악하는 구조를 가져가겠습니다.
결측치를 파악했으니, 결측치를 제거해야 해요.

df.dropna( ) 함수를 이용해 특정 변수의 결측치를 제거할 수 있었어요.
df.dropna(subset = ['변수명'])을 입력해서 변수명의 결측치를 제거하는 원리에요.

물론, df.dropna( )를 이용해 변수 2개 이상의 결측치를 한 번에 제거할 수도 있어요.

일반적으로, subset으로 변수를 지정하지 않고 그냥 df.dropna( )를 입력해도 모든 결측치를 제거할 수 있어요.
단, subset으로 변수를 지정하지 않으면 편하지만, 분석에 필요한 행까지 손실되는 단점이 있데요.
그리고 의도하지 않게 분석에 사용할 수 있는 데이터까지 제거되는 문제가 발생해요.
저는 아직 코린이니까 책에서 권하는 방법대로, 분석에 사용할 변수를 직접 지정해 결측치를 제거하는 구조를 가져가겠습니다.
일반적으로,
데이터가 크고 결측치가 적을 때에는 결측치를 제거하고 분석해도 큰 문제는 없데요.
하지만,
데이터가 작고 결측치가 많을 때에는 결측치를 제거하면 분석 결과가 왜곡되는 문제가 발생해요.
이런 경우에는 결측치 대체법을 이용해 결측치를 제거하지 않고 다른 값을 이용합니다.
결측치 대체법을 통해 분석 결과가 왜곡되는 문제를 보완할 수 있어요.
결측치를 대체하는 방법은 평균이나 최빈값 등 대푯값을 이용하거나 통계 분석 기법으로 예측값을 추청하는 방법이 있어요.
저는 평균값으로 결측치를 대체해보는 실습을 했습니다.

잠깐 나왔지만, df.loc[ ]는 데이터 위치를 지정하는 역할이에요.
df.loc[행 위치, 열 위치] 형태로 입력해서, 열 위치(변수)과 행의 위치에 해당되는 값들을 다른 값으로 바꿀 수 있었어요.

평균을 구한 후, df.fillna( )를 이용해 결측치를 다른 값으로 대체할 수 있었어요.
df.fillna(숫자값) 혹은 df.fillna('문자값')의 형태로 ( 괄호 ) 안에 결측치를 대체할 값을 입력하는 원리에요.
여기서 궁금했던게, df.fillna( )의 괄호 안에 mean을 입력하면 안될까?가 궁금했어요.

궁금해서 바로 해봤어요.
3행 3열의 값이 결측치 NaN이었는데, 평균값으로 대체되더라고요.
지식 + 1

결측치를 대체했다면, 결측치가 무사히 대체되었는지 확인해야해요.
우선, df.isna( )를 이용해 결측치의 유무를 확인했고요.

df.isna( )에 sum( )을 적용해서 결측치의 빈도도 확인했어요.
이상치를 제거하는 실습도 했습니다.

의도적으로 이상치가 있는 예시 데이터 프레임을 만들었고요.

df.value_counts( )에 sort_index( )를 적용해 각 변수의 이상치를 확인했어요..
이상치 정제하는 방법은 이상치를 식별하고, 해당 이상치를 결측치로 변경하는 것으로 시작합니다.

이상치를 결측치로 바꾸기 위해서는 numpy패키지의 where 조건문을 사용했어요.
동시에, numpy패키지의 np.num을 이용해 결측치NaN을 지정할 수 있었어요.

이상치를 결측치로 대체해서 제거한 후, 분석에 왜곡을 줄일 수 있네요.
단, where 조건문으로 np.nan을 반환했는데 NaN이 아닌 문자 nan이 출력되는 경우가 있데요.
그럴 때에는 결측치를 의미하는 임의의 문자를 할당하고 df.replace( )를 사용한다고 합니다.


df.replace( )함수는,
df.replace( 기존 데이터, 신규 데이터 )의 구조를 가집니다.
기존의 데이터를 신규 데이터로 변경하는 원리에요.
여기까지 정리하면,
1단계 : 데이터의 개략적인 구조 확인
2단계 : 이상치 유무 및 빈도 파악
3단계 : 이상치를 결측치로 대체
4단계 : 결측치 유무 및 빈도 파악
5단계 : 결측치 대체 및 4단계 반복
6단계 : 데이터 분석
위 6개 단계로 데이터 분석을 해서 분석 결과에 왜곡을 줄일 수 있어요.
마지막으로 극단치를 제거하는 실습을 했어요.
극단치를 제거하려면 정상범위를 지정해야 합니다.
주로 Box Plot을 이용해 중심에서 벗어난 값을 극단치를 간주하는 방법이 있어요.
Box Plot은 가우스 분포를 직사각형의 상자 모양으로 표현한 그래프입니다.

Box Plot은 seaborn 패키지로 그릴 수 있었어요.
sns.boxplot(data = 데이터프레임이름, y = '변수')의 형태로 작성해요.
특히, ( 괄호 )안에 data를 지정할 때에는 ' 따옴표 '를 작성하지 않아야 해요.
위 상자 그래프를 읽는 방법은 추후에 포스팅으로 다뤄보겠습니다.
극단치의 제거하는 과정은 4단계에요.
1단계 : 1사분위수와 3사분위수를 구하기
2단계 : IQR (Inter Quartile Range, 사분위 범위) 구하기
3단계 : 극단치 경계 (하한값, 상한값) 구하기
4단계 : 극단치를 결측 처리하기
1단계 : 1사분위수, 3사분위수 구하기

1사분위수와 3사분위수는 df.quantile( ) 함수를 이용해 구할 수 있었어요.
1사분위수 : 하위 25%에 해당하는 값
3사분위수 : 하위 75%에 해당하는 값
df.quantile(.25)는 1사분위수, df.quantile(.75)는 3사분위수를 구할 때 사용해요.
2단계 : IQR 구하기

IQR은 3사분위수에서 1사분위수를 뺀 값이에요.
3단계 : 극단치의 경계 (하한값, 상한값) 구하기

하한값 = 1사분위수보다 IQR의 1.5배만큼 작은 값
상한값 = 3사분위수보다 IQR의 1.5배만큼 큰 값
4단계 : 극단치를 결측 처리하기

극단치를 결측치로 처리할 때에는, numpy패키지의 where조건문을 사용했어요.
극단치를 제거한 후, 다시 box plot으로 그려보았어요.

통계 처리를 통해, 극단치인 값들이 결측치로 전환된 값은 3개라는 것을 알 수 있었어요.
오늘 배운 극단치, 이상치, 결측치를 정제하는 방법은 중요한 개념인 거 같아요.
1단계 : 데이터의 개략적인 구조 확인
2단계 : 극단치 유무 파악
3단계 : IOR 계산으로 극단치를 결측치로 대체 및 제거
4단계 : 이상치 유무 및 빈도 파악
5단계 : 이상치를 결측치로 대체
6단계 : 결측치 유무 및 빈도 파악
7단계 : 결측치 대체 및 4단계 반복
8단계 : 데이터 분석
이렇게 데이터 분석 과정에 대해 정리할 수 있을꺼 같네요.
정리해볼게요.
함수
pandas.isna( ) : 결측치 유무 확인
pandas.isna( ).sum( ) : 결측치 빈도 확인
df.dropna(subset = ['변수명']) : '변수명'의 결측치 제거
df.fillna(숫자) : 데이터를 숫자로 대체
df.fillna('문자') : 데이터를 문자로 대체
df.replace('데이터1', '데이터2') : 데이터1을 데이터2로 변경
seaborn.boxplot(data = 데이터프레임, y ='변수명') : '변수명'을 y값으로 데이터프레임의 box plot
다음에는 box plot를 해석하는 방법에 대해 공부한 후, 포스팅 하겠습니다.
'Python 데이터 분석 입문' 카테고리의 다른 글
| (Python 데이터 분석 입문 07편) 그래프 그리기: Scatter Plot, Bar Chart, Line Chart, Box Plot (0) | 2025.12.22 |
|---|---|
| (데이터 분석 공부 1편) Box Plot 읽기 (0) | 2025.12.22 |
| (Python 데이터 분석 입문 05편) 데이터 전처리(下): 열 추가하기, 조건별 요약하기, 행/열 합치기 (0) | 2025.12.20 |
| (Python 데이터 분석 입문 04편) 데이터 전처리(上): 행 추출하기, 열 추출하기, 정렬하기 (0) | 2025.12.12 |
| (Python 데이터 분석 입문 03편) 데이터 파악하기, 변수명 바꾸기, 파생변수 만들기, 그래프로 시각화하기 (0) | 2025.12.07 |