공공데이터를 활용한 Pandas 기초 실습(결측값 처리~)
28 May 2023 -
21 minute read
작성자 : 양한나
1. 실습에 사용할 데이터를 편집해보자.
- 오늘 사용할 자료는 학생건강검사_2021년_원자료.csv 파일입니다. 간단한 실습에 알맞게 이것저것 편집해봅시다. 실습자료
import pandas as pd
import numpy as np
df=pd.read_csv("/Users/asd00/Desktop/Ch 03. 데이터 전처리/수정할데이터.csv",encoding='cp949')
df[:5]
#cp949는 한글 인코딩의 한 종류입니다. pd.read_csv()를 사용할 때 종종 오류가 나는 경우가 있으니 오류로
#'UnicodeDecodeError'가 뜨면 'utf-8'이나 'cp949','euc-kr'등을 사용해보시길 바랍니다.
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게 건강검진_종합소견
0 2021 34.687664 129 1. 대도시/중소도시 충북 남 20140209 20210610.0 121.0 24.200001 정상
1 2021 41.323936 104 1. 대도시/중소도시 대전 남 20141113 20210719.0 126.0 28.400000 정상
2 2021 24.419891 123 1. 대도시/중소도시 제주 남 20141215 20210409.0 123.8 28.000000 정상(경계)
3 2021 22.338629 109 1. 대도시/중소도시 세종 남 20141011 20210607.0 116.1 21.299999 정상
4 2021 43.717056 120 1. 대도시/중소도시 전북 남 20140204 20210603.0 121.4 23.799999 정밀검사요함
#실습하며 변하는 값들을 용이하게 알아보기 위해 50행까지 잘라줍니다.
#sample(frac=1)함수를 사용하여 행을 마구잡이로 섞어준 뒤 인덱스를 재정렬하고 df에 저장합니다.
df=df.sample(frac=1).reset_index(drop=True)
df=df.iloc[:50]
print(len(df))
50
#데이터가 잘 섞인 것을 확인할 수 있습니다.
df[:5]
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게 건강검진_종합소견
0 2021 23.328217 53 1. 대도시/중소도시 경북 여 20060123 20210819.0 160.20000 61.700001 NaN
1 2021 46.369274 112 1. 대도시/중소도시 울산 남 20120816 20210420.0 128.00000 32.200001 NaN
2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.89999 27.600000 정상
3 2021 25.170055 85 1. 대도시/중소도시 충북 남 20080218 20210422.0 175.80000 60.000000 정상
4 2021 29.561989 3 2. 읍지역 강원 여 20040318 20210719.0 163.20000 48.599998 NaN
#실습 목적의 데이터 수정이기 때문에 '키'column의 값을 5개 정도를 NaN값으로 바꾸어 주겠습니다.
#무작위로 선택하기 위해 random을 import합니다.
import random
lst=[random.randint(0,50) for _ in range(5)]
for i in lst:
df['키'][i]=np.NaN
#수정한 df는 아래처럼 따로 저장해줍시다.
df.to_csv("/Users/asd00/Desktop/Ch 03. 데이터 전처리/수정된데이터.csv")
2.수정된 데이터를 확인해보자.
#수정된 csv파일을 새로 불러와줍시다.
df=pd.read_csv("/Users/asd00/Desktop/Ch 03. 데이터 전처리/수정된데이터.csv",encoding="utf-8")
#다섯 줄만 확인해볼까요?
df.head()
Unnamed: 0 학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게 건강검진_종합소견
0 0 2021 23.328217 53 1. 대도시/중소도시 경북 여 20060123 20210819.0 160.20000 61.700001 NaN
1 1 2021 46.369274 112 1. 대도시/중소도시 울산 남 20120816 20210420.0 128.00000 32.200001 NaN
2 2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.89999 27.600000 정상
3 3 2021 25.170055 85 1. 대도시/중소도시 충북 남 20080218 20210422.0 175.80000 60.000000 정상
4 4 2021 29.561989 3 2. 읍지역 강원 여 20040318 20210719.0 163.20000 48.599998 NaN
#['Unnamed: 0'] column은 불필요합니다.
#해당 column을 삭제할 수도 있겠지만 파일을 다른 방식으로 한번 더 불러봅시다.
df=pd.read_csv("/Users/asd00/Desktop/Ch 03. 데이터 전처리/수정된데이터.csv",encoding="utf-8",index_col=0)
df.head()
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게 건강검진_종합소견
0 2021 23.328217 53 1. 대도시/중소도시 경북 여 20060123 20210819.0 160.20000 61.700001 NaN
1 2021 46.369274 112 1. 대도시/중소도시 울산 남 20120816 20210420.0 128.00000 32.200001 NaN
2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.89999 27.600000 정상
3 2021 25.170055 85 1. 대도시/중소도시 충북 남 20080218 20210422.0 175.80000 60.000000 정상
4 2021 29.561989 3 2. 읍지역 강원 여 20040318 20210719.0 163.20000 48.599998 NaN
#실습 이전에 데이터를 쭉 확인해봅시다.
df
#해당 파일은 ['건강검진_종합소견']칼럼에 다량의 결측값을 포함합니다. ['키']칼럼에도 5개의 결측값을 포함하고 있습니다.
#실습에선 이 데이터에 행 또는 열을 추가/삭제하고, 결측값을 여러 방식으로 처리해볼 예정입니다.
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게 건강검진_종합소견
0 2021 23.328217 53 1. 대도시/중소도시 경북 여 20060123 20210819.0 160.20000 61.700001 NaN
1 2021 46.369274 112 1. 대도시/중소도시 울산 남 20120816 20210420.0 128.00000 32.200001 NaN
2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.89999 27.600000 정상
3 2021 25.170055 85 1. 대도시/중소도시 충북 남 20080218 20210422.0 175.80000 60.000000 정상
4 2021 29.561989 3 2. 읍지역 강원 여 20040318 20210719.0 163.20000 48.599998 NaN
5 2021 8.559022 26 2. 읍지역 울산 여 20050519 20210322.0 157.00000 45.000000 정상
6 2021 31.989246 53 1. 대도시/중소도시 경북 여 20080217 20210712.0 158.70000 54.700001 정밀검사요함
7 2021 57.781227 50 1. 대도시/중소도시 경남 남 20071122 20210416.0 163.30000 52.200001 NaN
8 2021 27.776781 14 1. 대도시/중소도시 대구 여 20050905 20210402.0 164.30000 52.400002 정상(경계)
9 2021 30.774267 10 1. 대도시/중소도시 경북 여 20040716 20210616.0 164.70000 52.700001 NaN
10 2021 114.727410 64 1. 대도시/중소도시 서울 여 20071123 20210511.0 154.60001 48.900002 NaN
11 2021 28.404102 10 1. 대도시/중소도시 경북 여 20051216 20210527.0 159.50000 80.199997 정밀검사요함
12 2021 73.986015 120 1. 대도시/중소도시 전북 남 20100112 20210722.0 NaN 46.400002 NaN
13 2021 31.590971 60 1. 대도시/중소도시 대전 여 20060919 20210910.0 NaN 59.200001 NaN
14 2021 22.767038 53 1. 대도시/중소도시 경북 여 20071203 20210427.0 161.50000 70.400002 NaN
15 2021 40.564987 71 1. 대도시/중소도시 인천 남 20080215 20210511.0 161.89999 45.700001 정밀검사요함
16 2021 35.157436 101 1. 대도시/중소도시 대구 여 20140303 20210329.0 124.70000 24.200001 정상
17 2021 22.281324 12 2. 읍지역 경북 여 20050105 20210616.0 155.20000 57.299999 NaN
18 2021 80.866142 20 1. 대도시/중소도시 서울 여 20051025 20210506.0 158.39999 46.900002 NaN
19 2021 17.877020 68 1. 대도시/중소도시 울산 남 20080812 20210414.0 169.50000 74.099998 정밀검사요함
20 2021 28.806343 1 1. 대도시/중소도시 강원 남 20030404 20210506.0 174.10001 69.300003 NaN
21 2021 72.317360 4 1. 대도시/중소도시 경기 여 20030917 20210616.0 160.20000 55.000000 NaN
22 2021 47.379448 119 2. 읍지역 전남 남 20090129 20210511.0 161.50000 71.400002 NaN
23 2021 61.222218 115 1. 대도시/중소도시 인천 남 20110621 20210624.0 137.70000 30.000000 정상
24 2021 24.712151 39 3. 도서벽지/면지역 충남 남 20030301 20210401.0 179.00000 77.000000 NaN
25 2021 35.645729 112 1. 대도시/중소도시 울산 여 20100116 20210405.0 152.50000 58.000000 NaN
26 2021 29.677813 112 1. 대도시/중소도시 울산 여 20130906 20210522.0 129.70000 30.299999 NaN
27 2021 44.383324 88 1. 대도시/중소도시 강원 여 20130820 20210909.0 134.89999 27.100000 NaN
28 2021 20.161478 38 1. 대도시/중소도시 충남 여 20050623 20210702.0 160.89999 56.200001 정상
29 2021 15.181579 65 1. 대도시/중소도시 세종 남 20070929 20210831.0 158.70000 41.400002 NaN
30 2021 95.082298 64 1. 대도시/중소도시 서울 여 20071028 20210510.0 158.70000 57.500000 NaN
31 2021 30.238064 27 1. 대도시/중소도시 인천 여 20031020 20210510.0 164.80000 54.599998 NaN
32 2021 24.965509 60 1. 대도시/중소도시 대전 여 20060106 20210315.0 161.00000 46.000000 NaN
33 2021 43.435921 104 1. 대도시/중소도시 대전 남 20111209 20210702.0 143.70000 39.599998 정밀검사요함
34 2021 79.330093 4 1. 대도시/중소도시 경기 남 20051130 20210518.0 171.20000 51.200001 정밀검사요함
35 2021 56.952087 126 1. 대도시/중소도시 충남 여 20140715 20210408.0 120.60000 26.700001 정밀검사요함
36 2021 8.956521 67 2. 읍지역 세종 여 20070527 20210712.0 NaN 59.200001 NaN
37 2021 542.851750 127 3. 도서벽지/면지역 충남 남 20120220 20210414.0 145.60001 49.799999 NaN
38 2021 21.612099 38 1. 대도시/중소도시 충남 여 20051213 20210520.0 157.80000 49.900002 정밀검사요함
39 2021 48.070133 56 1. 대도시/중소도시 광주 남 20080516 20210626.0 168.70000 46.900002 정밀검사요함
40 2021 60.742973 20 1. 대도시/중소도시 서울 여 20041123 20210701.0 168.60001 65.500000 NaN
41 2021 27.684238 17 1. 대도시/중소도시 대전 여 20040628 20210729.0 161.60001 51.400002 NaN
42 2021 35.701881 56 1. 대도시/중소도시 광주 여 20081230 20210601.0 NaN 63.099998 정밀검사요함
43 2021 15.477712 65 1. 대도시/중소도시 세종 여 20070724 20210510.0 157.10001 54.400002 NaN
44 2021 54.350529 4 1. 대도시/중소도시 경기 여 20050517 20210823.0 162.50000 48.099998 정상
45 2021 46.585281 101 1. 대도시/중소도시 대구 여 20121106 20210621.0 136.30000 29.600000 NaN
46 2021 70.016350 105 1. 대도시/중소도시 부산 남 20100201 20210605.0 143.39999 32.599998 NaN
47 2021 27.585751 82 1. 대도시/중소도시 충남 여 20080301 20210913.0 161.00000 49.200001 정상
48 2021 29.002300 24 1. 대도시/중소도시 울산 여 20040304 20210727.0 171.60001 76.099998 NaN
49 2021 33.326992 10 1. 대도시/중소도시 경북 남 20030614 20210618.0 NaN 56.500000 NaN
3.결측값 확인하기
- 실습데이터는 50개의 행만 포함하지만, 행이 아주 많은 데이터라면 어디에 결측값이 하나씩 확인할 수 없겠죠?isnull()을 사용하여 df 각 칼럼의 결측값을 확인해봅시다.
df.isnull().sum()
#isnull()은 결측값만 True로 반환합니다. .sum()을 isnull()과 같이 사용하면 각 column의 True 값을 1로 하여 더해줍니다.
학년도 0
최종가중치 0
strata 0
도시규모 0
시도 0
성별 0
생년월일 0
건강검진일 0
키 5
몸무게 0
건강검진_종합소견 31
dtype: int64
#결측치가 포함된 행을 지우고 싶습니다. dropna()는 결측값을 포함한 행을 삭제합니다.
#어떤 문제가 생기는지 확인합시다.
df.dropna()
- 행이 18개밖에 안 남았습니다. 이유는 ‘건강검진_종합소견’column이 너무 많은 결측값을 포함하기 때문입니다. #때문에 ‘건강검진_종합소견’칼럼을 먼저 지워주도록 하겠습니다.
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게 건강검진_종합소견
2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.89999 27.600000 정상
3 2021 25.170055 85 1. 대도시/중소도시 충북 남 20080218 20210422.0 175.80000 60.000000 정상
5 2021 8.559022 26 2. 읍지역 울산 여 20050519 20210322.0 157.00000 45.000000 정상
6 2021 31.989246 53 1. 대도시/중소도시 경북 여 20080217 20210712.0 158.70000 54.700001 정밀검사요함
8 2021 27.776781 14 1. 대도시/중소도시 대구 여 20050905 20210402.0 164.30000 52.400002 정상(경계)
11 2021 28.404102 10 1. 대도시/중소도시 경북 여 20051216 20210527.0 159.50000 80.199997 정밀검사요함
15 2021 40.564987 71 1. 대도시/중소도시 인천 남 20080215 20210511.0 161.89999 45.700001 정밀검사요함
16 2021 35.157436 101 1. 대도시/중소도시 대구 여 20140303 20210329.0 124.70000 24.200001 정상
19 2021 17.877020 68 1. 대도시/중소도시 울산 남 20080812 20210414.0 169.50000 74.099998 정밀검사요함
23 2021 61.222218 115 1. 대도시/중소도시 인천 남 20110621 20210624.0 137.70000 30.000000 정상
28 2021 20.161478 38 1. 대도시/중소도시 충남 여 20050623 20210702.0 160.89999 56.200001 정상
33 2021 43.435921 104 1. 대도시/중소도시 대전 남 20111209 20210702.0 143.70000 39.599998 정밀검사요함
34 2021 79.330093 4 1. 대도시/중소도시 경기 남 20051130 20210518.0 171.20000 51.200001 정밀검사요함
35 2021 56.952087 126 1. 대도시/중소도시 충남 여 20140715 20210408.0 120.60000 26.700001 정밀검사요함
38 2021 21.612099 38 1. 대도시/중소도시 충남 여 20051213 20210520.0 157.80000 49.900002 정밀검사요함
39 2021 48.070133 56 1. 대도시/중소도시 광주 남 20080516 20210626.0 168.70000 46.900002 정밀검사요함
44 2021 54.350529 4 1. 대도시/중소도시 경기 여 20050517 20210823.0 162.50000 48.099998 정상
47 2021 27.585751 82 1. 대도시/중소도시 충남 여 20080301 20210913.0 161.00000 49.200001 정상
#['건겅검진_종합소견']칼럼을 삭제하기 위해 drop()을 사용합니다. 열을 삭제하기 때문에 axis=True
df.drop('건강검진_종합소견',axis=True)[:5]
#해당 column이 잘 지워지는 걸 확인했으니 inplace=True로 저장하고 데이터를 다시 확인해봅시다.
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게
0 2021 23.328217 53 1. 대도시/중소도시 경북 여 20060123 20210819.0 160.20000 61.700001
1 2021 46.369274 112 1. 대도시/중소도시 울산 남 20120816 20210420.0 128.00000 32.200001
2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.89999 27.600000
3 2021 25.170055 85 1. 대도시/중소도시 충북 남 20080218 20210422.0 175.80000 60.000000
4 2021 29.561989 3 2. 읍지역 강원 여 20040318 20210719.0 163.20000 48.599998
#칼럼이 잘 지워진 걸 확인했으면 inplace=True를 사용하여 df를 저장해줍시다.
df.drop('건강검진_종합소견',axis=1,inplace=True)
#결측값의 개수를 다시 확인해볼까요?
df.isnull().sum()
학년도 0
최종가중치 0
strata 0
도시규모 0
시도 0
성별 0
생년월일 0
건강검진일 0
키 5
몸무게 0
dtype: int64
- 결측값이 포함된 행을 지우지 말고 [‘키’]의 결측값을 대체해봅시다.해당 실습을 위해 결측값을 가진 행 5개와 다른 행 5개를 df2에 저장해줍시다. 별 의미는 없고, 실습결과 확인을 위해 df를 다 출력하면 포스트가 너무 길어질 것 같아서입니다.. 빈 데이터프레임을 만들어줍니다.
df2=pd.DataFrame()
#isna()메소드는 결측값이 있을 때 True를 반환합니다.
#append()메소드로 데이터를 추가할 수 있습니다.
for i in range(50):
if pd.isna(df.loc[i]['키']):
involveNan=df.loc[i]
df2=df2.append(involveNan,ignore_index=True)
df2
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게
0 2021 73.986015 120 1. 대도시/중소도시 전북 남 20100112 20210722.0 NaN 46.400002
1 2021 31.590971 60 1. 대도시/중소도시 대전 여 20060919 20210910.0 NaN 59.200001
2 2021 8.956521 67 2. 읍지역 세종 여 20070527 20210712.0 NaN 59.200001
3 2021 35.701881 56 1. 대도시/중소도시 광주 여 20081230 20210601.0 NaN 63.099998
4 2021 33.326992 10 1. 대도시/중소도시 경북 남 20030614 20210618.0 NaN 56.500000
#결측값을 포함하지 않은 행 5개도 포함하겠습니다.
a=True
while a==True:
random_numbers = random.sample(range(0,50), 5)
for i in random_numbers:
if pd.isna(df.loc[i]['키']):
pass
else:
a=False
for i in random_numbers:
df2=df2.append(df.loc[i],ignore_index=True)
df2
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게
0 2021 73.986015 120 1. 대도시/중소도시 전북 남 20100112 20210722.0 NaN 46.400002
1 2021 31.590971 60 1. 대도시/중소도시 대전 여 20060919 20210910.0 NaN 59.200001
2 2021 8.956521 67 2. 읍지역 세종 여 20070527 20210712.0 NaN 59.200001
3 2021 35.701881 56 1. 대도시/중소도시 광주 여 20081230 20210601.0 NaN 63.099998
4 2021 33.326992 10 1. 대도시/중소도시 경북 남 20030614 20210618.0 NaN 56.500000
5 2021 21.612099 38 1. 대도시/중소도시 충남 여 20051213 20210520.0 157.80000 49.900002
6 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.89999 27.600000
7 2021 70.016350 105 1. 대도시/중소도시 부산 남 20100201 20210605.0 143.39999 32.599998
8 2021 72.317360 4 1. 대도시/중소도시 경기 여 20030917 20210616.0 160.20000 55.000000
9 2021 54.350529 4 1. 대도시/중소도시 경기 여 20050517 20210823.0 162.50000 48.099998
df2=df2.sample(frac=1).reset_index(drop=True)
df2
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게
0 2021 33.326992 10 1. 대도시/중소도시 경북 남 20030614 20210618.0 NaN 56.500000
1 2021 70.016350 105 1. 대도시/중소도시 부산 남 20100201 20210605.0 143.39999 32.599998
2 2021 8.956521 67 2. 읍지역 세종 여 20070527 20210712.0 NaN 59.200001
3 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.89999 27.600000
4 2021 21.612099 38 1. 대도시/중소도시 충남 여 20051213 20210520.0 157.80000 49.900002
5 2021 73.986015 120 1. 대도시/중소도시 전북 남 20100112 20210722.0 NaN 46.400002
6 2021 35.701881 56 1. 대도시/중소도시 광주 여 20081230 20210601.0 NaN 63.099998
7 2021 72.317360 4 1. 대도시/중소도시 경기 여 20030917 20210616.0 160.20000 55.000000
8 2021 31.590971 60 1. 대도시/중소도시 대전 여 20060919 20210910.0 NaN 59.200001
9 2021 54.350529 4 1. 대도시/중소도시 경기 여 20050517 20210823.0 162.50000 48.099998
- 결측값을 특정값 ‘0’으로 대체해봅시다.
df2.fillna(0)
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게
0 2021 33.326992 10 1. 대도시/중소도시 경북 남 20030614 20210618.0 0.00000 56.500000
1 2021 70.016350 105 1. 대도시/중소도시 부산 남 20100201 20210605.0 143.39999 32.599998
2 2021 8.956521 67 2. 읍지역 세종 여 20070527 20210712.0 0.00000 59.200001
3 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.89999 27.600000
4 2021 21.612099 38 1. 대도시/중소도시 충남 여 20051213 20210520.0 157.80000 49.900002
5 2021 73.986015 120 1. 대도시/중소도시 전북 남 20100112 20210722.0 0.00000 46.400002
6 2021 35.701881 56 1. 대도시/중소도시 광주 여 20081230 20210601.0 0.00000 63.099998
7 2021 72.317360 4 1. 대도시/중소도시 경기 여 20030917 20210616.0 160.20000 55.000000
8 2021 31.590971 60 1. 대도시/중소도시 대전 여 20060919 20210910.0 0.00000 59.200001
9 2021 54.350529 4 1. 대도시/중소도시 경기 여 20050517 20210823.0 162.50000 48.099998
- 결측 값을 직전 행의 값으로 대체합니다. ‘ffill’은 직전 행의 값으로 대체합니다. 다음 행이 존재하지 않거나 NaN이면 채워주지 않습니다.
df2.fillna(method='ffill')
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게
0 2021 33.326992 10 1. 대도시/중소도시 경북 남 20030614 20210618.0 NaN 56.500000
1 2021 70.016350 105 1. 대도시/중소도시 부산 남 20100201 20210605.0 143.39999 32.599998
2 2021 8.956521 67 2. 읍지역 세종 여 20070527 20210712.0 143.39999 59.200001
3 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.89999 27.600000
4 2021 21.612099 38 1. 대도시/중소도시 충남 여 20051213 20210520.0 157.80000 49.900002
5 2021 73.986015 120 1. 대도시/중소도시 전북 남 20100112 20210722.0 157.80000 46.400002
6 2021 35.701881 56 1. 대도시/중소도시 광주 여 20081230 20210601.0 157.80000 63.099998
7 2021 72.317360 4 1. 대도시/중소도시 경기 여 20030917 20210616.0 160.20000 55.000000
8 2021 31.590971 60 1. 대도시/중소도시 대전 여 20060919 20210910.0 160.20000 59.200001
9 2021 54.350529 4 1. 대도시/중소도시 경기 여 20050517 20210823.0 162.50000 48.099998
#평균 값 대체
df2.fillna(df2.mean()['키'])
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게
0 2021 33.326992 10 1. 대도시/중소도시 경북 남 20030614 20210618.0 151.359996 56.500000
1 2021 70.016350 105 1. 대도시/중소도시 부산 남 20100201 20210605.0 143.399990 32.599998
2 2021 8.956521 67 2. 읍지역 세종 여 20070527 20210712.0 151.359996 59.200001
3 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.899990 27.600000
4 2021 21.612099 38 1. 대도시/중소도시 충남 여 20051213 20210520.0 157.800000 49.900002
5 2021 73.986015 120 1. 대도시/중소도시 전북 남 20100112 20210722.0 151.359996 46.400002
6 2021 35.701881 56 1. 대도시/중소도시 광주 여 20081230 20210601.0 151.359996 63.099998
7 2021 72.317360 4 1. 대도시/중소도시 경기 여 20030917 20210616.0 160.200000 55.000000
8 2021 31.590971 60 1. 대도시/중소도시 대전 여 20060919 20210910.0 151.359996 59.200001
9 2021 54.350529 4 1. 대도시/중소도시 경기 여 20050517 20210823.0 162.500000 48.099998
- 이번엔 좀 더 의미있는 값으로 대체해봅시다.df2 집단의 키가 다양하기 때문에 결측값을 가진 행의 몸무게로 키를 예상하겠습니다. 평균 bmi를 활용하겠습니다. 평균 bmi를 20이라고 칩시다.
#bmi= (몸무게) ÷ (키*0.01)2
# 키=sqrt(몸무게/20)*100
import math
for i in range(10):
if pd.isna(df2.loc[i]['키']):
a=df2.loc[i,'몸무게']
df2.loc[i,'키']=math.sqrt(a/20)*100
df2
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게
0 2021 33.326992 10 1. 대도시/중소도시 경북 남 20030614 20210618.0 168.077363 56.500000
1 2021 70.016350 105 1. 대도시/중소도시 부산 남 20100201 20210605.0 143.399990 32.599998
2 2021 8.956521 67 2. 읍지역 세종 여 20070527 20210712.0 172.046507 59.200001
3 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.899990 27.600000
4 2021 21.612099 38 1. 대도시/중소도시 충남 여 20051213 20210520.0 157.800000 49.900002
5 2021 73.986015 120 1. 대도시/중소도시 전북 남 20100112 20210722.0 152.315465 46.400002
6 2021 35.701881 56 1. 대도시/중소도시 광주 여 20081230 20210601.0 177.623194 63.099998
7 2021 72.317360 4 1. 대도시/중소도시 경기 여 20030917 20210616.0 160.200000 55.000000
8 2021 31.590971 60 1. 대도시/중소도시 대전 여 20060919 20210910.0 172.046507 59.200001
9 2021 54.350529 4 1. 대도시/중소도시 경기 여 20050517 20210823.0 162.500000 48.099998
- 같은 방법으로 df의 결측값도 대체합시다. 이제 어떤 칼럼도 결측값을 포함하지 않습니다.
for i in range(50):
if pd.isna(df.loc[i]['키']):
a=df.loc[i,'몸무게']
df.loc[i,'키']=math.sqrt(a/20)*100
df.isnull().sum()
학년도 0
최종가중치 0
strata 0
도시규모 0
시도 0
성별 0
생년월일 0
건강검진일 0
키 0
몸무게 0
dtype: int64
4.타입변환
- 각 colunm의 타입을 확인합시다.
df.dtypes
학년도 int64
최종가중치 float64
strata int64
도시규모 object
시도 object
성별 object
생년월일 int64
건강검진일 float64
키 float64
몸무게 float64
dtype: object
- ‘키’와 ‘몸무게’를 정수형으로 변환해줍시다.
df.astype({'키':'int','몸무게':'int'})[:5]
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게
0 2021 23.328217 53 1. 대도시/중소도시 경북 여 20060123 20210819.0 160 61
1 2021 46.369274 112 1. 대도시/중소도시 울산 남 20120816 20210420.0 128 32
2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132 27
3 2021 25.170055 85 1. 대도시/중소도시 충북 남 20080218 20210422.0 175 60
4 2021 29.561989 3 2. 읍지역 강원 여 20040318 20210719.0 163 48
- astype을 적용한 값과 df의 원래 값을 비교해보면 float형을 int형으로 바꾸면서 소수점을 버린 걸 알 수 있습니다.
df[:5]
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게
0 2021 23.328217 53 1. 대도시/중소도시 경북 여 20060123 20210819.0 160.20000 61.700001
1 2021 46.369274 112 1. 대도시/중소도시 울산 남 20120816 20210420.0 128.00000 32.200001
2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.89999 27.600000
3 2021 25.170055 85 1. 대도시/중소도시 충북 남 20080218 20210422.0 175.80000 60.000000
4 2021 29.561989 3 2. 읍지역 강원 여 20040318 20210719.0 163.20000 48.599998
- 그대로 저장해줍시다.
df=df.astype({'키':'int','몸무게':'int'})
df.head()
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게
0 2021 23.328217 53 1. 대도시/중소도시 경북 여 20060123 20210819.0 160 61
1 2021 46.369274 112 1. 대도시/중소도시 울산 남 20120816 20210420.0 128 32
2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132 27
3 2021 25.170055 85 1. 대도시/중소도시 충북 남 20080218 20210422.0 175 60
4 2021 29.561989 3 2. 읍지역 강원 여 20040318 20210719.0 163 48
- 타입을 다시 확인합시다.
df.dtypes
학년도 int64
최종가중치 float64
strata int64
도시규모 object
시도 object
성별 object
생년월일 int64
건강검진일 float64
키 int32
몸무게 int32
dtype: object
#한 학생의 키를 '-'로 바꾸어보겠습니다.
df.loc[3,'키']='-'
df.astype({'키':'int'})
#'키'가 '-'문자를 포함하기 때문에 int형으로 바꿀 수 없습니다.
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[200], line 1
----> 1 df.astype({'키':'int'})
2 #'키'가 '-'문자를 포함하기 때문에 int형으로 바꿀 수 없습니다.
File c:\Users\asd00\AppData\Local\Programs\Python\Python311\Lib\site-packages\pandas\core\generic.py:6226, in NDFrame.astype(self, dtype, copy, errors)
6224 res_col = col.copy() if copy else col
6225 else:
-> 6226 res_col = col.astype(dtype=cdt, copy=copy, errors=errors)
6227 results.append(res_col)
6229 elif is_extension_array_dtype(dtype) and self.ndim > 1:
6230 # GH 18099/22869: columnwise conversion to extension dtype
6231 # GH 24704: use iloc to handle duplicate column names
6232 # TODO(EA2D): special case not needed with 2D EAs
File c:\Users\asd00\AppData\Local\Programs\Python\Python311\Lib\site-packages\pandas\core\generic.py:6240, in NDFrame.astype(self, dtype, copy, errors)
6233 results = [
6234 self.iloc[:, i].astype(dtype, copy=copy)
6235 for i in range(len(self.columns))
6236 ]
6238 else:
6239 # else, only a single dtype is given
-> 6240 new_data = self._mgr.astype(dtype=dtype, copy=copy, errors=errors)
6241 return self._constructor(new_data).__finalize__(self, method="astype")
...
169 # Explicit copy, or required since NumPy can't view from / to object.
--> 170 return arr.astype(dtype, copy=True)
172 return arr.astype(dtype, copy=copy)
ValueError: invalid literal for int() with base 10: '-'
Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings...
- to_nemeric은 datatype을 숫자형식으로 바꿔줍니다. errors=’coerce’ 변환할 수 없는 값을 결측값으로 지정합니다.ㅍ’-‘가 결측값으로 바뀐 걸 확인할 수 있습니다.
df['키']=pd.to_numeric(df['키'],errors='coerce')
- 이제 결측값을 삭제하고 ‘키’칼럼을 int형으로 바꿀 수 있습니다.
df=df.dropna()
df.astype({'키':'int'})
df.reset_index(inplace=True)
df.drop(['index'],axis=1,inplace=True)
df[:5]
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게
0 2021 23.328217 53 1. 대도시/중소도시 경북 여 20060123 20210819.0 160.0 61
1 2021 46.369274 112 1. 대도시/중소도시 울산 남 20120816 20210420.0 128.0 32
2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.0 27
3 2021 29.561989 3 2. 읍지역 강원 여 20040318 20210719.0 163.0 48
4 2021 8.559022 26 2. 읍지역 울산 여 20050519 20210322.0 157.0 45
df[:5]
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게
0 2021 23.328217 53 1. 대도시/중소도시 경북 여 20060123 20210819.0 160.0 61
1 2021 46.369274 112 1. 대도시/중소도시 울산 남 20120816 20210420.0 128.0 32
2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.0 27
3 2021 29.561989 3 2. 읍지역 강원 여 20040318 20210719.0 163.0 48
4 2021 8.559022 26 2. 읍지역 울산 여 20050519 20210322.0 157.0 45
5.콜럼 추가 삭제
- 추가(append)와 삭제(drop)는 위에서 데이터를 수정하며 다루었기 때문에 그냥 넘어갑시다. 다른 칼럼들을 이용하여 [‘bmi’]칼럼을 추가해봅시다.
df['bmi']=df['몸무게']/(df['키']*0.01)**2
df[:5]
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게 bmi
0 2021 23.328217 53 1. 대도시/중소도시 경북 여 20060123 20210819.0 160.0 61 23.828125
1 2021 46.369274 112 1. 대도시/중소도시 울산 남 20120816 20210420.0 128.0 32 19.531250
2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.0 27 15.495868
3 2021 29.561989 3 2. 읍지역 강원 여 20040318 20210719.0 163.0 48 18.066167
4 2021 8.559022 26 2. 읍지역 울산 여 20050519 20210322.0 157.0 45 18.256319
6.apply/map을 활용한 데이터 변환
- ‘bmi’column을 활용하여 ‘bmi’가 18.5~22.9면 ‘정상’, 그 미만면 ‘저체중’ ,나머지는 과체중으로 표시한 ‘비만도’column을 만들어봅시다.
df['비만도']=0
df[:5]
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게 bmi 비만도
0 2021 23.328217 53 1. 대도시/중소도시 경북 여 20060123 20210819.0 160.0 61 23.828125 0
1 2021 46.369274 112 1. 대도시/중소도시 울산 남 20120816 20210420.0 128.0 32 19.531250 0
2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.0 27 15.495868 0
3 2021 29.561989 3 2. 읍지역 강원 여 20040318 20210719.0 163.0 48 18.066167 0
4 2021 8.559022 26 2. 읍지역 울산 여 20050519 20210322.0 157.0 45 18.256319 0
a=df[(df['bmi']>=18.5) &( df['bmi']<=22.9)]
df['비만도'][a.index]='정상'
a=df[df['bmi']<18.5]
df['비만도'][a.index]='저체중'
a=df[df['bmi']>22.9]
df['비만도'][a.index]='과체중'
df[:5]
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게 bmi 비만도
0 2021 23.328217 53 1. 대도시/중소도시 경북 여 20060123 20210819.0 160.0 61 23.828125 과체중
1 2021 46.369274 112 1. 대도시/중소도시 울산 남 20120816 20210420.0 128.0 32 19.531250 정상
2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.0 27 15.495868 저체중
3 2021 29.561989 3 2. 읍지역 강원 여 20040318 20210719.0 163.0 48 18.066167 저체중
4 2021 8.559022 26 2. 읍지역 울산 여 20050519 20210322.0 157.0 45 18.256319 저체중
- 이번엔 어플라이와 함수를 이용하여 [‘비만도2’]column을 추가해봅시다. 먼저 함수를 만들어줍시다.
def case_function(x):
if x>22.9:
return '과체중'
elif x<18.5:
return '저체중'
else:
return '정상'
- 판다스의 apply()메소드를 사용하면 데이터프레임의 행 또는 열에 함수를 적용할 수 있습니다. axis=1이면 당연히 열에 적용되겠죠?
df['비만도2']=df['bmi'].apply(case_function)
df[:5]
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게 bmi 비만도 비만도2
0 2021 23.328217 53 1. 대도시/중소도시 경북 여 20060123 20210819.0 160.0 61 23.828125 과체중 과체중
1 2021 46.369274 112 1. 대도시/중소도시 울산 남 20120816 20210420.0 128.0 32 19.531250 정상 정상
2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.0 27 5.495868 저체중 저체중
3 2021 29.561989 3 2. 읍지역 강원 여 20040318 20210719.0 163.0 48 18.066167 저체중 저체중
4 2021 8.559022 26 2. 읍지역 울산 여 20050519 20210322.0 157.0 45 18.256319 저체중 저체중
- map이용할 수도 있습니다. 3개의 행만 가져와서 실습해보겠습니다. df3의 ‘비만도3’ 열을 생성하고, df3의 인덱스를 사용하여 a 딕셔너리를 매핑하여 값을 할당합니다.ㅊdf3의 인덱스에 해당하는 값들은 a 딕셔너리의 키로 사용되고, 매핑되는 값은 ‘비만도3’ 열에 할당됩니다.
df3=df[:3]
a={0:'과체중',1:'정상',2:'과체중'}
df3['비만도3']=df3.index.map(a)
df3
학년도 최종가중치 strata 도시규모 시도 성별 생년월일 건강검진일 키 몸무게 bmi 비만도 비만도2 비만도3
0 2021 23.328217 53 1. 대도시/중소도시 경북 여 20060123 20210819.0 160.0 61 23.828125 과체중 과체중 과체중
1 2021 46.369274 112 1. 대도시/중소도시 울산 남 20120816 20210420.0 128.0 32 19.531250 정상 정상 정상
2 2021 124.663180 129 1. 대도시/중소도시 충북 여 20111222 20210715.0 132.0 27 15.495868 저체중 저체중 과체중
7.실습
- #실습이 끝난 df파일을 새로 저장하며 실습을 마무리하겠습니다.
df.to_csv('/Users/asd00/Desktop/Ch 03. 데이터 전처리/230526실습데이터.csv', index=False)
- 끝