240919
복습
In [380]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
In [382]:
path = 'https://bit.ly/HRDBEmployee'
employee = pd.read_csv(path, header = 0) # header 로 몇행 부터 읽을지 정할 수 있음
employee.head()
Out[382]:
EmpIDEmpNameEngNameGenderMaritalYNHireDateRetireDateDeptIDPhoneEMailSalary01234
S0001 | 홍길동 | hong | M | Y | 2017-01-01 | NaN | SYS | 010-1234-1234 | hong@d-friends.co.kr | 8500.0 |
S0002 | 일지매 | jiemae | M | Y | 2017-01-12 | NaN | GEN | 017-111-1222 | jimae@d-friends.co.kr | 8300.0 |
S0003 | 강우동 | NaN | M | N | 2018-04-01 | NaN | SYS | 010-1222-2221 | woodong@d-friends.co.kr | 6500.0 |
S0004 | 김삼순 | samsam | F | Y | 2018-08-01 | NaN | MKT | 010-3212-3212 | samsoon.kim@d-friends.co.kr | 7000.0 |
S0005 | 오삼식 | three | M | N | 2019-01-01 | 2021-01-31 | MKT | 010-9876-5432 | samsik@d-friends.co.kr | 6400.0 |
In [383]:
# 원하는 열만 조회
employee.loc[:,['EmpID', 'EmpName', 'DeptID', 'Phone']].head()
# 다른 방법
employee[['EmpID', 'EmpName', 'DeptID', 'Phone']].head()
Out[383]:
EmpIDEmpNameDeptIDPhone01234
S0001 | 홍길동 | SYS | 010-1234-1234 |
S0002 | 일지매 | GEN | 017-111-1222 |
S0003 | 강우동 | SYS | 010-1222-2221 |
S0004 | 김삼순 | MKT | 010-3212-3212 |
S0005 | 오삼식 | MKT | 010-9876-5432 |
In [386]:
emp01 = employee[['EmpID', 'EmpName', 'DeptID', 'Phone', 'Salary']].copy()
# SYS 부서만 조회
emp_sys = emp01.loc[emp01['DeptID'] == 'SYS']
emp_sys
Out[386]:
EmpIDEmpNameDeptIDPhoneSalary028101218
S0001 | 홍길동 | SYS | 010-1234-1234 | 8500.0 |
S0003 | 강우동 | SYS | 010-1222-2221 | 6500.0 |
S0009 | 최사모 | SYS | 011-899-9988 | 5800.0 |
S0011 | 오감자 | SYS | 010-6655-7788 | 4700.0 |
S0013 | 한국인 | SYS | 010-6611-1266 | 4500.0 |
S0019 | 정주고 | SYS | 010-7777-2277 | 6000.0 |
In [388]:
# 인덱스 초기화
emp_sys.reset_index(drop = True, inplace = True)
emp_sys
Out[388]:
EmpIDEmpNameDeptIDPhoneSalary012345
S0001 | 홍길동 | SYS | 010-1234-1234 | 8500.0 |
S0003 | 강우동 | SYS | 010-1222-2221 | 6500.0 |
S0009 | 최사모 | SYS | 011-899-9988 | 5800.0 |
S0011 | 오감자 | SYS | 010-6655-7788 | 4700.0 |
S0013 | 한국인 | SYS | 010-6611-1266 | 4500.0 |
S0019 | 정주고 | SYS | 010-7777-2277 | 6000.0 |
In [390]:
#DeptID 별 Salary 합 집계
sum_salary = employee.groupby('DeptID', as_index = False)[['Salary']].sum()
sum_salary
Out[390]:
DeptIDSalary012345
ACC | 10000.0 |
GEN | 14800.0 |
HRD | 24800.0 |
MKT | 28100.0 |
STG | 0.0 |
SYS | 36000.0 |
- astype(x) 메소드: 자료형을 x로 변환
In [393]:
# Salary열 int 변환
sum_salary['Salary'] = sum_salary['Salary'].astype(int)
sum_salary
Out[393]:
DeptIDSalary012345
ACC | 10000 |
GEN | 14800 |
HRD | 24800 |
MKT | 28100 |
STG | 0 |
SYS | 36000 |
데이터프레임 변경 (1)
열 변경
- rename() : dictionary 형태로 열 이름 변경
- df.columns = [ ] : 모든 열 이름 변경
In [397]:
path = 'https://raw.githubusercontent.com/Jangrae/csv/master/tips(2).csv'
tip = pd.read_csv(path)
tip.head()
Out[397]:
total_bill_amounttipmale_femalesmoke_yes_noweek_namedinner_lunchsize01234
16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
In [399]:
tip1 = tip.rename(columns = {'total_bill_amount': 'total_bill', 'male_female': 'sex'})
tip1
Out[399]:
total_billtipsexsmoke_yes_noweek_namedinner_lunchsize01234...239240241242243
16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
... | ... | ... | ... | ... | ... | ... |
29.03 | 5.92 | Male | No | Sat | Dinner | 3 |
27.18 | 2.00 | Female | Yes | Sat | Dinner | 2 |
22.67 | 2.00 | Male | Yes | Sat | Dinner | 2 |
17.82 | 1.75 | Male | No | Sat | Dinner | 2 |
18.78 | 3.00 | Female | No | Thur | Dinner | 2 |
244 rows × 7 columns
In [401]:
tip.columns = ['total_bill', 'tip', 'sex', 'smoker', 'day', 'time', 'size']
tip
Out[401]:
total_billtipsexsmokerdaytimesize01234...239240241242243
16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
... | ... | ... | ... | ... | ... | ... |
29.03 | 5.92 | Male | No | Sat | Dinner | 3 |
27.18 | 2.00 | Female | Yes | Sat | Dinner | 2 |
22.67 | 2.00 | Male | Yes | Sat | Dinner | 2 |
17.82 | 1.75 | Male | No | Sat | Dinner | 2 |
18.78 | 3.00 | Female | No | Thur | Dinner | 2 |
244 rows × 7 columns
열 추가
- dictionary 처럼 추가
- insert(index, '열 이름', 열 값)
In [404]:
tip.head()
Out[404]:
total_billtipsexsmokerdaytimesize01234
16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
In [406]:
# 'final_amt' 열 추가
tip['final_amt'] = tip['total_bill'] + tip['tip']
tip.head()
Out[406]:
total_billtipsexsmokerdaytimesizefinal_amt01234
16.99 | 1.01 | Female | No | Sun | Dinner | 2 | 18.00 |
10.34 | 1.66 | Male | No | Sun | Dinner | 3 | 12.00 |
21.01 | 3.50 | Male | No | Sun | Dinner | 3 | 24.51 |
23.68 | 3.31 | Male | No | Sun | Dinner | 2 | 26.99 |
24.59 | 3.61 | Female | No | Sun | Dinner | 4 | 28.20 |
In [408]:
# insert()로 'div_tb'열 추가
tip.insert(1, 'div_tb', tip['total_bill']/tip['size'])
tip.head()
Out[408]:
total_billdiv_tbtipsexsmokerdaytimesizefinal_amt01234
16.99 | 8.495000 | 1.01 | Female | No | Sun | Dinner | 2 | 18.00 |
10.34 | 3.446667 | 1.66 | Male | No | Sun | Dinner | 3 | 12.00 |
21.01 | 7.003333 | 3.50 | Male | No | Sun | Dinner | 3 | 24.51 |
23.68 | 11.840000 | 3.31 | Male | No | Sun | Dinner | 2 | 26.99 |
24.59 | 6.147500 | 3.61 | Female | No | Sun | Dinner | 4 | 28.20 |
열 삭제
- drop()메서드
In [411]:
drop_col = ['final_amt']
tip.drop(columns = drop_col, inplace = True)
tip
Out[411]:
total_billdiv_tbtipsexsmokerdaytimesize01234...239240241242243
16.99 | 8.495000 | 1.01 | Female | No | Sun | Dinner | 2 |
10.34 | 3.446667 | 1.66 | Male | No | Sun | Dinner | 3 |
21.01 | 7.003333 | 3.50 | Male | No | Sun | Dinner | 3 |
23.68 | 11.840000 | 3.31 | Male | No | Sun | Dinner | 2 |
24.59 | 6.147500 | 3.61 | Female | No | Sun | Dinner | 4 |
... | ... | ... | ... | ... | ... | ... | ... |
29.03 | 9.676667 | 5.92 | Male | No | Sat | Dinner | 3 |
27.18 | 13.590000 | 2.00 | Female | Yes | Sat | Dinner | 2 |
22.67 | 11.335000 | 2.00 | Male | Yes | Sat | Dinner | 2 |
17.82 | 8.910000 | 1.75 | Male | No | Sat | Dinner | 2 |
18.78 | 9.390000 | 3.00 | Female | No | Thur | Dinner | 2 |
244 rows × 8 columns
In [413]:
# 여러 열 동시에 삭제
drop_cols = ['div_tb', 'size']
tip.drop(columns = drop_cols, inplace = True)
tip.head()
Out[413]:
total_billtipsexsmokerdaytime01234
16.99 | 1.01 | Female | No | Sun | Dinner |
10.34 | 1.66 | Male | No | Sun | Dinner |
21.01 | 3.50 | Male | No | Sun | Dinner |
23.68 | 3.31 | Male | No | Sun | Dinner |
24.59 | 3.61 | Female | No | Sun | Dinner |
범주값 변경
- map(딕셔너리) : 한 번만 실행, 여러 번 실행 시 오류 발생
- replace(딕셔너리) : 여러 번 실행 가능
In [415]:
tip['sex'] = tip['sex'].map({'Male': 1, 'Female': 0})
tip.head()
Out[415]:
total_billtipsexsmokerdaytime01234
16.99 | 1.01 | 0 | No | Sun | Dinner |
10.34 | 1.66 | 1 | No | Sun | Dinner |
21.01 | 3.50 | 1 | No | Sun | Dinner |
23.68 | 3.31 | 1 | No | Sun | Dinner |
24.59 | 3.61 | 0 | No | Sun | Dinner |
In [417]:
tip['smoker'] = tip['smoker'].replace({1:'Male', 0:'Female'})
tip.head()
Out[417]:
total_billtipsexsmokerdaytime01234
16.99 | 1.01 | 0 | No | Sun | Dinner |
10.34 | 1.66 | 1 | No | Sun | Dinner |
21.01 | 3.50 | 1 | No | Sun | Dinner |
23.68 | 3.31 | 1 | No | Sun | Dinner |
24.59 | 3.61 | 0 | No | Sun | Dinner |
범주값 만들기
- pd.cut(범주화할 데이터, 개수, label = 이름) 메서드 : 크기 기준으로 구간 분리
- pd.qcut() 메서드 : 개수 기준으로 구간 분리
In [424]:
# 'tip_grp'이라는 새로운 열 만듦
tip['tip_grp'] = pd.cut(tip['tip'], 4, labels = list('abcd'))
tip.head()
Out[424]:
total_billtipsexsmokerdaytimetip_grp01234
16.99 | 1.01 | 0 | No | Sun | Dinner | a |
10.34 | 1.66 | 1 | No | Sun | Dinner | a |
21.01 | 3.50 | 1 | No | Sun | Dinner | b |
23.68 | 3.31 | 1 | No | Sun | Dinner | b |
24.59 | 3.61 | 0 | No | Sun | Dinner | b |
In [426]:
tip['tip_grp'].value_counts()
Out[426]:
tip_grp
a 163
b 69
c 10
d 2
Name: count, dtype: int64
In [434]:
q1 = tip['tip'].describe()['25%']
q2 = tip['tip'].describe()['50%']
q3 = tip['tip'].describe()['75%']
bin = [-np.inf, q1, q2, q3, np.inf] # q1 이하 / q1 초과 q2 이하 / q2 초과 q3 이하 / q3 초과
label = list('abcd')
tip['tip_group'] = pd.cut(tip['tip'], bins = bin, labels = label)
tip['tip_grp'].value_counts()
Out[434]:
tip_grp
a 163
b 69
c 10
d 2
Name: count, dtype: int64
데이터프레임 변경 (2)
결측치 찾기
- isnull() : 결측치면 True, 유효값이면 False
- isna() = isnull()
- notnull() : 결측치면 False, 유효값이면 True
In [439]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
path = 'https://raw.githubusercontent.com/Jangrae/csv/master/airquality.csv'
air = pd.read_csv(path)
air.head()
Out[439]:
OzoneSolar.RWindTempMonthDay01234
41.0 | 190.0 | 7.4 | 67 | 5 | 1 |
36.0 | 118.0 | 8.0 | 72 | 5 | 2 |
12.0 | 149.0 | 12.6 | 74 | 5 | 3 |
18.0 | 313.0 | 11.5 | 62 | 5 | 4 |
NaN | NaN | 14.3 | 56 | 5 | 5 |
In [440]:
air.isnull()
Out[440]:
OzoneSolar.RWindTempMonthDay01234...148149150151152
False | False | False | False | False | False |
False | False | False | False | False | False |
False | False | False | False | False | False |
False | False | False | False | False | False |
True | True | False | False | False | False |
... | ... | ... | ... | ... | ... |
False | False | False | False | False | False |
True | False | False | False | False | False |
False | False | False | False | False | False |
False | False | False | False | False | False |
False | False | False | False | False | False |
153 rows × 6 columns
In [441]:
# 열 별 결측치 개수
air.isnull().sum()
Out[441]:
Ozone 37
Solar.R 7
Wind 0
Temp 0
Month 0
Day 0
dtype: int64
결측치 제거, 채우기
- dropna() : inplace, axis
- fillna() : 결측치 부분만 채우기
- ffill() : Forward Fill 결측치를 바로 앞의 값으로 변경
- bfill() : Backward Fill 결측치를 바로 뒤의 값으로 변경
- interpolate() : 결측치를 선형보간법으로 변경
In [443]:
air_test = air.copy()
air_test.dropna(inplace = True)
# dropna로 결측치 제거 후 결측치 개수 확인
air_test.isnull().sum()
Out[443]:
Ozone 0
Solar.R 0
Wind 0
Temp 0
Month 0
Day 0
dtype: int64
In [444]:
air_test = air.copy()
# air_test의 'Ozone' 열의 결측치 개수 #37
air_test['Ozone'].isnull().sum()
Out[444]:
37
In [450]:
#결측치를 'Ozone'의 평균으로 대체
Ozone_mean = air_test['Ozone'].mean()
air_test['Ozone'] = air_test['Ozone'].fillna(Ozone_mean)
# 결측치 개수 확인
air_test['Ozone'].isnull().sum()
Out[450]:
0
In [452]:
air_test['Solar.R'].isnull().sum()
Out[452]:
7
In [454]:
# 결측치를 0으로 채움
air_test['Solar.R'] = air_test['Solar.R'].fillna(0)
# 결측치 개수 확인
air_test['Solar.R'].isnull().sum()
Out[454]:
0
In [456]:
air_test = air.copy()
# 결측치 개수확인
air_test.isnull().sum()
Out[456]:
Ozone 37
Solar.R 7
Wind 0
Temp 0
Month 0
Day 0
dtype: int64
In [458]:
# ffill()로 결측치 채우기
air_test['Ozone'] = air_test['Ozone'].ffill()
# bfill()로 결측치 채우기
air_test['Solar.R'] = air_test['Solar.R'].bfill()
# 확인
air_test.isnull().sum()
Out[458]:
Ozone 0
Solar.R 0
Wind 0
Temp 0
Month 0
Day 0
dtype: int64
In [460]:
# interpolate()로 결측치 채우기
air_test = air.copy()
air_test['Ozone'] = air_test['Ozone'].interpolate()
air_test.isnull().sum()
Out[460]:
Ozone 0
Solar.R 7
Wind 0
Temp 0
Month 0
Day 0
dtype: int64
가변수 (Dummy Variable) 만들기
- pd.get_dummies(변환하려는 데이터, columns = 변환할 열, drop_first = ?, dtype = 저장하는 데이터 타입) 함수
- drop_first = True
In [463]:
path = 'https://raw.githubusercontent.com/jangrae/csv/master/tips.csv'
tip = pd.read_csv(path)
tip.head()
Out[463]:
total_billtipsexsmokerdaytimesize01234
16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
In [464]:
# 1. 범주형 변수 찾기
tip.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 244 entries, 0 to 243
Data columns (total 7 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 total_bill 244 non-null float64
1 tip 244 non-null float64
2 sex 244 non-null object
3 smoker 244 non-null object
4 day 244 non-null object
5 time 244 non-null object
6 size 244 non-null int64
dtypes: float64(2), int64(1), object(4)
memory usage: 13.5+ KB
In [465]:
# 2. 범주형 변수(object) 'sex','smoker','day', 'time'을 가변수화
dumm_col = ['sex','smoker','day', 'time']
tip = pd.get_dummies(tip, columns = dumm_col, drop_first = True, dtype = int)
tip.head()
Out[465]:
total_billtipsizesex_Malesmoker_Yesday_Satday_Sunday_Thurtime_Lunch01234
16.99 | 1.01 | 2 | 0 | 0 | 0 | 1 | 0 | 0 |
10.34 | 1.66 | 3 | 1 | 0 | 0 | 1 | 0 | 0 |
21.01 | 3.50 | 3 | 1 | 0 | 0 | 1 | 0 | 0 |
23.68 | 3.31 | 2 | 1 | 0 | 0 | 1 | 0 | 0 |
24.59 | 3.61 | 4 | 0 | 0 | 0 | 1 | 0 | 0 |