python / pandas(결측치 치환, 파생변수 추가)
073 판다스에서 결측치(NaN) 확인하기
결측치란 데이터가 없는 상태를 말하는데 데이터를 만드는 사람이 실수로 데이터를 입력하지 않은 경우도 있고 실제로 데이터가 없어서 데이터가 없는 상태를 말하는데 통계 데이터 분석을 하든 머신러닝을 하든 결측치가 없는 데이터가 제공되어야 보다 더 정확하게 데이터 분석을 할 수 있음.
좋은 데이터가 있어야 좋은 인공지능 모델을 생성할 수 있음.
NaN ---> Not a Number
NA ---> Not Available
예제. emp 판다스 데이터프레임에서 결측치를 확인하시오.
emp.isnull().sum()
#Unnamed: 0 0
#empno 0
#ename 0
#job 0
#mgr 1
#hiredate 0
#sal 0
#comm 10
#deptno 0
문제261. 백화점 데이터에서 결측치를 확인하시오.
x_train.isnull().sum()
# cust_id 0
# 총구매액 0
# 최대구매액 0
# 환불금액 2295
# 주구매상품 0
# 주구매지점 0
# 내점일수 0
# 내점당구매건수 0
# 주말방문비율 0
# 구매주기 0
백화점 데이터의 경우 전체 3500건 중에서 2295건이 결측치로 보이고 있음. 이렇게 결측치가 너무 많으면 기계 학습 시킬때 도움이 되지 않음.
ㅇ 결측치 처리하는 방법
1. 결측치가 너무 많으면 해당 컬럼(변수)을 삭제시킴.
2. 그렇지 않다면 아래 4가지 방법을 이용해서 결측치를 다른 값으로 치환함.
- 최빈값으로 치환
- 결측치 주변의 값으로 치환
- 평균값으로 치환
- 회귀를 이용한 예측값으로 치환
문제262.백화점 데이터에서 환불금액 컬럼을 drop하시오.
x_train.drop(['환불금액'],axis=1,inplace=True)
# inplace = True를 쓰면 실제로 해당 컬럼이 삭제가 되는 것이고
# inplace = False를 쓰거나 inplace를 안쓰면 그냥 삭제된 상태로 보이는 것
# axis = 1 --> 열삭제
# axis = 0 --> 행삭제
x_train.columns # x_train 데이터 프레임의 컬럼들을 확인
문제263. 커미션이 null인 사원들의 이름과 커미션을 출력하시오.
-- SQL
select ename, comm
from emp
where comm is null;
# 판다스
emp[['ename','comm']][emp['comm'].isnull()]
문제264. 커미션이 null이 아닌 사원들의 이름과 커미션을 출력하시오.
emp[['ename','comm']][~emp['comm'].isnull()]
문제265. 사원 데이터 프레임의 comm 컬럼을 drop하시오.
emp.drop(['comm'],axis=1)
문제266. 사원 테이블의 결측치가 있다면 행을 삭제하시오.
emp.dropna(axis=0, inplace= True)
emp
# dropna()는 결측치를 삭제하는 함수
문제267. 사원 테이블의 커미션에 결측치가 있는 행들을 삭제하시오.
emp = emp.dropna(subset=['comm'])
emp
# subset[컬럼] 설정하면 컬럼에 결측치가 있는 데이터만 삭제됨
ㅇ 결측치를 다른 값으로 치환하는 방법
- 최빈값으로 치환
- 결측치 주변의 값으로 치환
- 평균값으로 치환
- 회귀를 이용한 예측값으로 치환
문제268. 타이타닉호의 승객 데이터를 로드해서 tat라는 데이터 프레임을 생성하시오
import seaborn as sns
tat = sns.load_dataset('titanic')
tat
문제269. tat데이터 프레임에서 결측치가 많은 컬럼이 무엇인지 확인하시오.
tat.isnull().sum()
# survived 0
# pclass 0
# sex 0
# age 177 <== 결측치가 많음
# sibsp 0
# parch 0
# fare 0
# embarked 2
# class 0
# who 0
# adult_male 0
# deck 688
# embark_town 2
# alive 0
# alone 0
문제270. 결측치 평균값으로 치환하기 / tat 데이터프레임의 age 컬럼 결측치를 나이의 평균값으로 치환하시오.
mean_age = tat['age'].mean()
mean_age
tat['age'].fillna(mean_age, inplace = True)
# fillna(결측치에 채워넣을 값) : 결측치를 채우는 함수
문제271. 사원 테이블의 커미션의 결측치를 커미션의 평균값으로 치환하시오.
mean_comm = emp['comm'].mean()
mean_comm
emp['comm'].fillna(mean_comm,inplace=True)
emp
문제272. 결측치 최빈값으로 치환하기 / 다시 타이타닉 데이터를 로드해서 데이터 프레임 tat를 만들고 나이의 결측치를 나이의 최빈값으로 치환하시오.
most_age = tat['age'].value_counts(dropna=True).idxmax()
tat['age'].fillna(most_age,inplace=True)
tat
fillna함수는 결측치를 다른값으로 치환할 때 쓰는 판다스 시리즈 함수
inplace = True를 쓰게 되면 실제로 데이터 프레임 컬럼의 데이터값이 변경됨.
문제273. emp 데이터 프레임의 mgr의 결측치를 최빈값으로 치환하시오.
emp = pd.read_csv("c:\\data\\emp2.csv")
most_mgr = emp['mgr'].value_counts(dropna=True).idxmax()
emp['mgr'].fillna(most_mgr, inplace=True)
emp
문제274. 위의 결과를 보면 mgr이 실수형으로 출력되는데 정수형으로 변경되게 하시오
most_mgr = emp['mgr'].value_counts(dropna=True).idxmax()
emp['mgr'].fillna(most_mgr, inplace=True)
emp['mgr'] = emp['mgr'].apply(int)
emp
문제275. 결측치 주변값으로 치환하기 / 타이타닉의 deck(정박한 항구)의 결측치를 주변의 데이터로 치환하시오.
tat = sns.load_dataset('titanic')
# tat['deck'].fillna(method='ffill', inplace = True) # 결측치 위의 데이터로 치환
tat['deck'].fillna(method='bfill', inplace = True) # 결측치 아래의 데이터로 치환
tat
문제276. 사원 데이터 프레임의 mgr의 결측치를 주변의 데이터로 치환하시오.(결측치 아래의 데이터로 치환)
emp=pd.read_csv("c:\\data\\emp2.csv")
emp['mgr'].fillna(method='bfill', inplace = True)
emp
074 판다스에서 파생변수 추가하는 방법
오라클로 말하면 컬럼을 추가하는 것인데 이 컬럼의 데이터가 기계가 학습하기에 좋은 데이터를 파생변수라고 함.
예제. 타이타닉 호의 생존자를 예측하는 기계학습 모델을 생성한다고 하면 이 모델이 생존자를 잘 예측하기 위해 좋은 학습 데이터를 제공해야함.
기존의 데이터를 가지고 새롭게 가공해서 만든 새로운 컬럼을 파생변수라고 함.
타이타닉 데이터에서의 좋은 파생변수는? 여자, 아이
여자 또는 아이면 1이라고 하고 아니면 0이라고 하는 파생변수를 woman_child라는 이름으로 생성해보자.
문제277. 타이타닉 데이터에서 성별, 성별별 인원수를 출력하시오
tat.groupby('sex')['survived'].count().reset_index()
# 결측치가 없는 컬럼을 넣으면 됨
# 아래와 같은 방법으로도 출력 가능
tat['sex'].value_counts(dropna=False)
+) dropna의 차이
tat['deck'].value_counts(dropna=False) # 결측치 count
# C 249
# B 203
# D 155
# E 136
# F 65
# A 64
# G 18
# NaN 1
tat['deck'].value_counts(dropna=True) # 결측치 제외
# C 249
# B 203
# D 155
# E 136
# F 65
# A 64
# G 18
문제278. 생존여부, 생존여부별 인원수를 출력하시오.
tat['survived'].value_counts(dropna=False)
# 0 549 사망자
# 1 342 생존자
문제279. 나이가 10살 미만인 승객들은 모두 몇 명인가?
tat[tat['age'] < 10].count()
문제280. 성별이 여자이거나 나이가 10살 미만인 승객은 전부 몇명인가?
tat[(tat['age']<10)|(tat['sex']=='female')].count()
문제281. 성별이 여자이거나 나이가 16살 미만인 승객을 1이라고 하고 아니면 0이라고 하는 파생변수를 woman_child라는 이름으로 생성하시오.
mask = (tat['age']<16)|(tat['sex']=='female')
mask
tat['woman_child'] = mask.astype(int) # True는 1이 나오고 False는 0이 나옴
tat
문제282. 사원 테이블에서 누가 퇴사할 것 같은지를 예측하기 위한 머신러닝 모델을 만들기 위해서 파생변수를 생성하겠음.
emp = pd.read_csv("c:\\data\\emp2.csv")
ret = emp['sal']< 2500
ret
emp['set_yn'] =ret.astype(int) #True = 1, False = 0
emp
이런 파생변수들이 기계가 잘 공부할 수 있도록 사람이 제공해줘야함.