[TIL-260413] 멋쟁이사자처럼 그로스마케팅 4기 - 데이터분석 개론 day23 | 데이터 이상치 및 결측치 처리
pamsyra2026. 4. 13. 17:12
▼오늘 배운 사항들 1. 라이브러리 2. Pandas로 이상치/결측치 처리 - 데이터 탐색 : df.info(), df.describe(), df.head() - 데이터 선택 : loc[], iloc[] - 결측치 파악 : df.isnull().sum() / .dropna(subset=), [''].fillna() - 이상치 파악 : .quantile(), .copy() - 데이터 처리(파생변수) : pd.cut()
Part 1. Pandas 로 이상치/결측치 처리를 위한 데이터 탐색 및 선택
[1. 데이터 탐색하기]
데이터를 받으면 무조건 이 세 줄 먼저 실행하기
데이터 분석 시, 데이터를 믿고 바로 계산하는 것이 가장 큰 실수 ▶ 함정 잡고 시작해야함 - ex. Age 컬럼에 999가 들어있다 → 평균 나이가 말도 안 되게 높게 나옴 - ex. Income 컬럼에 24개가 비어있다 → 평균 소득 계산이 틀림 - ex. date 컬럼이 숫자로 읽힌다 → 월별 분석 자체가 불가능
df.info()
컬럼 이름, 타입, 결측치 수를 한번에
컬럼 타입 + 결측치 수 확인 가능
df.describe()
숫자 컬럼의 평균·최솟값·최댓값 등 기초 통계
숫자 통계 확인 가능
df.head(n)
처음 n행 미리보기 (기본값 5)
[2. 데이터 꺼내기]
판다스에서 데이터를 꺼내는 건 2가지 방법 사용 : loc, iloc
loc[ '행' , '열'] → 조건 넣어서 꺼낼수도 있음
# 특정 컬럼 선택
df.loc[:, 'age'] # 모든 행의 age 컬럼
df.loc[:, ['name', 'age']] # 여러 컬럼
# 조건으로 행 필터링 ← 실무에서 가장 자주 씀
df.loc[df['service'] == '멜론'] # 멜론 사용자만
df.loc[df['age'] >= 25] # 25살 이상
행 조건에 슬라이싱 활용해서 특정 값까지만 꺼낼 수 있음
범위 설정은 지난시간 배운 슬라이싱 활용
df['']를 사용해서 조건에 맞는 값만 추출 가능
ex. 멜론 만 보고 싶어 / 25살 이하만 보고 싶어
행조건 + 특정 열 선택 - 행 조건 : 특정 나이대 - 열 선택 : Likes 부터 satisfaction까지
조건 2개 구하기 - 행 조건 : 나이가 25세 이상이면서, 동시에 서비스가 멜론인 사람 - 열 선택 : 생략 (= 데이터프레임 전체 열 추출) - 컬럼으로 받아올 것이니 df[] 쓰되 조건이니까 () 괄호 넣어주기
만족도가 높은 고객을 타겟으로 특정 마케팅 플랜을 수립할 수 있음 - satisfaction이 8 이상인 고객은 vip로 바꾸려고 할 때
grade plan 값을 초기화 하고 싶을 땐, none 활용 → 삭제 아님, 초기화!
'inplace = Ture' : 원본에서 컬럼 삭제하고 싶을 때 사용
df.loc[df['satisfation'] >=8] #SEPT1. 만족도가 8이상인 고객 확인
df.loc[df['satisfation'] >=8, grade] #STEP2. 그 것의 grade 컬럼만 확인을 하고
df.loc[df['satisfaction'] >= 8, 'grade'] = 'vip' #STEP3. 이것을 vip로 지정하겠다
df['grade'] = None #지정한 값들 초기화
df.drop(columns=['grade']) #원본은 삭제 안됨
df.drop(columns=['grade'], inplace=True) #원본 df에서 컬럼 삭제 원할시 사용
iloc[0] / iloc[0:5] / iloc[-1] 등등 확인 가능하여 맨 마지막 행을 보고 싶을 때 주로 사용
마케터는 loc 많이 씀
한 행이어도 데이터프레임 표 형식으로 보고 싶으면 대괄호 한 번 더 씌워주기
연습문제 뒤에서부터 3번째까지 행 추출 : [-3:] → 음수는 :위치를 뒤로!
Part 2. 결측치 처리
[결측치]
결측치 : 비어있는 값
결측치를 그냥두면 계산이 틀려지니 처리해야 함
컬럼별 결측치 개수, 비율, 결측치에 특정 값 채우기, 결측치 컬럼 삭제, 평균값 계산 등
df.isnull().sum()
컬럼별 결측치 개수
df.isnull().mean() * 100
결측치 비율(%)
df['컬럼명'].fillna(값)
결측치를 특정 값으로 채우기
df.dropna(subset=['컬럼명'])
특정 컬럼이 비어있는 행 제거
df['컬럼명'].mean()
평균값 계산
df['컬럼명'].median()
중앙값 계산
dropna(subset=[]) : 결측치 값이 있는 행 삭제
# 방법 1: 행 제거 — 결측 비율이 낮을 때
df.dropna(subset=['likes']) # likes가 None인 Carol, Grace 행이 제거됨
#원본데이터에도 적용 방법
df.dropna(subset=['likes'], inplace=True) #1. inplace = True 사용
df = df.dropna(subset=['likes']) #2. df 값에 아예 넣어버리기
.fillna('') : none 값에 문자열 채우기
.fillna( df['income'].median()) : 결측치를 중앙값으로 채울 때 - 마케팅은 한쪽으로 치우친 값이 많기 때문에 평균보다 중앙값이 안전하니까! - 중앙값보다 그룹별 중앙값을 넣는 걸 추천
fillna 괄호 안에 중앙값 넣어주면 됨 -> hank의 income이 변했습니다.
[선택 예시]
결측치 5% 미만이면, 그냥 행제거
숫자값 컬럼 비워져있으면, fillna 중앙값 채우기
문자열데이터가 비워져있는데 필요한 데이터면, fillna에 미응답
그룹자체 특성이 많은데 소득을 구해야하는 상황이면, 그룹별 중앙값 채우기
[이상치]
이상치 : 다른값들과 동떨어진 비정상적인 값
이상치 값의 기준 IQR 방식 ↓
#중간 50%데이터가 퍼진 범위를 IQR - 앞에서 25프로 뒤에서 25프로
# 기초 통계로 먼저 확인
df['age'].describe() # max가 말도 안 되게 크면 이상치!
# IQR 방식으로 이상치 기준 계산
Q1 = df['age'].quantile(0.25)
Q3 = df['age'].quantile(0.75)
IQR = Q3 - Q1
upper = Q3 + 1.5 * IQR # 이 값보다 크면 이상치 상한선 식 by. 통계학자
# 이상치 확인 후 제거
df_clean = df[df['age'] <= upper].copy()
ex. 나이가 51.5가 넘으면 이상한 값이다라고 판단
.copy() 사용해서 이상치 제거한 값만 활용 가능
IQR을 구하고 이상치 기준을 구할 수 있음
[파생변수]
파생변수는 원재료를 마케터가 실제로 쓸 수 있는 지표로 바꾸는 작업 - 출생연도 → 나이 → 연령대 → "30대 타겟" 캠페인 필터 - 카테고리별 구매금액 → 총 구매금액 → 고가치 고객 식별 - 만족도 점수 → VIP / 일반 → VIP에게 리뷰 요청, 일반에게 재구매 쿠폰 - 구매수 / 조회수 → 전환율 → 전환율 낮은 고객에게 리타겟팅 광고
[pd.cut]
# pd.cut : 숫자를 구간으로 나눠주는 함수
# 필요한 것 : 어떤 컬럼 사용할지 / 어떤 구간으로 나눌지 / 나눈 구간을 지칭할 이름
#새로운 age_grop으로 지정해주기
df['age_group'] = pd.cut(
df['age'], # 어떤 컬럼 사용할지
bins = [0,29,39,49,100], # 어떤 구간으로 나눌지
labels = ['20대', '30대', '40대', '50대+']
)
[group by]
마케터의 대부분은 전체평균이 아닌 세그먼트별 특징값을 보는 것
세그먼트 별 특징에 따라 마케팅 플랜을 따로 수립
따라서 그룹바이가 중요함
[agg]
데이터별 집계 함수를 한꺼번에 확인하기 - 좋아요 수 합계, 만족도 중앙값, 수입 중앙값 등 보고 싶은 데이터를 agg를 사용해 확인 가능 - name count는 서비스별로 몇 명 쓰는지 보려고
#sql의 grupby와 같음
#문법 체크 : 괄호-대괄호 사용
#숫자 처리 : round()
#내림차순 : .sort_valuses(ascending=)
df.groupby('service')['satisfaction'].mean().round(2).sort_values(ascending=False)
#보고싶은 집계 함수를 한 번에?!
#agg써서 키값 한번에 확인하기
df.groupby('service').agg({
'satisfaction' : 'mean',
'income' : 'mean',
'name' : 'count' })
agg : sum('likes')같은것도 한번에 볼 수있음
[실습 - 이상치/결측치 데이터 처리 단계]
비어있는 값 채우기 : 결측치 확인 후 5개 fillna로 결측값 바꾸기
이상한 값 바꾸기/삭제하기 : describe로 이상치 확인 후 → IQR 구해서 이상치 조건 만든 copy 데이터 생성
파생변수 생성해서 데이터 정리하기 - pd.cut : 구간대 분류 후 분류값 부여 - loc : 특정 조건에 지정값 입력