☑️ 문제5. 이상치 처리
[문제]
- 1) 전체 데이터 결측값 처리 (삭제)
- 2) Quantity, UnitPrice 0 이하 제거
- 3)상품코드가 일반적이지 않은 경우
- StockCode 중 다음과 같이 문자로만 구성된 경우는 일반적이지 않은 경우로 보고, 숫자를 한개이상 포함하지 않는 경우는 이상치로 정의, 데이터셋에서 제거하세요.
- 4) Quantity, UnitPrice 컬럼 IQR 기반 방법으로 이상치 제거
[문제 풀이]
내 코드
import pandas as pd
#데이터 확인
df = pd.read_csv('online_retail.csv', encoding="ISO-8859-1")
df.info()
#1. 결측 값 처리 (삭제 하기) : dropna
df.isna().sum()
df.dropna(inplace=True)
df.isna().sum() # 삭제 확인
# 2) Quantity, UnitPrice 0 이하 제거
df.shape #406829 # 행 확인
drop_con1 = (df['Quantity']<=0) | (df['UnitPrice']<=0) # 삭제할 조건
df.drop(index = df[drop_con1].index,inplace=True)
df.shape #397884 # 제거 후 행 갯수 확인
# 3)상품코드가 일반적이지 않은 경우 (숫자 미포함시 이상치)
con= df['StockCode'].str.contains(r'\d+') # 숫자가 한개 이상인거만 추출
df= df[con]
df.shape
#4. Quantity, UnitPrice 컬럼 IQR 기반 방법으로 이상치 제거
qun_q1,uni_q1=df[['Quantity','UnitPrice']].quantile(0.25)
qun_q3,uni_q3=df[['Quantity','UnitPrice']].quantile(0.75)
uni_iqr = uni_q3 -uni_q1
qun_iqr = qun_q3 -qun_q1
lower_bound_qun = qun_q1 - 1.5*qun_iqr
upper_bound_qun = qun_q3 + 1.5*qun_iqr
lower_bound_uni = uni_q1 - 1.5*uni_iqr
upper_bound_uni = uni_q3 + 1.5*uni_iqr
qun_con = (df['Quantity']<lower_bound_qun) | (df['Quantity']>upper_bound_qun)
uni_con = (df['UnitPrice']<lower_bound_qun) | (df['UnitPrice']>upper_bound_qun)
total_con = qun_con | uni_con
df.drop(index = df[total_con].index,inplace=True)
df.shape
수정 코드
#두개의 컬럼 이상치 제거시, 반복 수행문 함수 화 가능
def drop_outliers_iqr(df, column):
q1 = df[column].quantile(0.25)
q3 = df[column].quantile(0.75)
iqr = q3 - q1
lower_bound = q1 - 1.5 * iqr
upper_bound = q3 + 1.5 * iqr
df_drop_outlier = df[(df[column] >= lower_bound) & (df[column] <= upper_bound)] #포함
return df_drop_outlier
이슈 및 해결 과정
- 상품 코드 값이 숫자가 하나라도 포함되어있지 않으면 제거해라 (df 시리즈의 각각의 값에 숫자가 없는 행만 추출)
- 방법 1) 숫자가 한개 이상인 행만 추출 → df 에 저장
df['StockCode'].str.contains(r'\d+')df= df[con]
- 방법2) 숫자가 아예 없는 행만 추출 → drop
drop_con2 = ~ df['StockCode'].str.contains(r'\d+') # 숫자가 하나라도 없는 조건 정규표현식 메소드 활용df.drop(index = df[drop_con2].index)
- 방법3) apply & lambda ( 파이썬 메소드 활용하여 행단위 연산)
df['StockCode'].apply(lambda x : any(x.isdigit() for c in x))
- 방법1,2 가 성능면에서 빠름. str.~ 메소드 사용시 벡터 기반으로 접근함. 빠르게 연산 가능, apply 사용시 개별 행 하나하나 접근하여 연산 진행. 상대적으로 느릴 수 있음.
- `str.contains` 메소드는 df 시리즈의 각각의 문자열 값이 정규표현식 (~) 을 만족하는 행을 출력 해줌.
- 정규 표현 식은 : str.contains(r' 표현식 ') 형태로 사용 할수 있음
- `isdigit` 메소드는 파이썬 문자열 메소드, 해당 문자열이 숫자가 있는지 없는지 확인 해주는 함수
- 방법 1) 숫자가 한개 이상인 행만 추출 → df 에 저장
- 이상치 검사 코드 함수화 : 이상치 검사 여러컬럼에 적용해야할때 함수화 계산 할수있음
- df 에 columns 값만 바뀌면서 이상치 계산함. → 파라미터로 df, column 2개 받음
- 이상치 계산 코드 작성 (4분위수 계산, iqr 계산, 상*하한 이상치 계산, 정상값 행만 추출해서 리턴)
한줄 포인트
- 데이터 프레임의 1개의 컬럼( 시리즈) 값이 문자열일때, 접근하는 메소드는 str.~ 로 활용하면 빠름. 이상치 검사 시 여러개의 컬럼에 적용해야할 경우 함수화하여 적용 가능
'PYTHON' 카테고리의 다른 글
프로젝트 회고 | Kaggle 스타벅스 마케팅 데이터 분석 : 분석 개요 (0) | 2024.12.30 |
---|---|
실습 | PANDAS 누락 기간 생성 / 조건별 증감율 계산하기( date_range/reindex/apply) (1) | 2024.12.26 |
실습 | PANDAS 삼성전자 종가 데이터 전월비 증감율 구하기 (strftime / pct_change/shift) (1) | 2024.12.26 |
실습 | PANDAS 집계 함수/ 상관관계 / 산점도 그리기 ( agg/corr/ matplotlib vs seaborn) (0) | 2024.12.26 |
실습 | PANDAS 데이터프레임 조회/ 병합 /필터링 하기 (head, merge, fillna) (0) | 2024.12.24 |