카테고리 없음
[06] 판다스 데이터프레임 변경
root_go
2023. 8. 22. 14:59
5.데이터프레임 변경 (1)
- 데이터 전처리를 위해 꼭 익혀두어야 할 내용입니다.
- 반복 학습과 실습을 통해서 익숙해져야 합니다.
# 라이브러리 불러오기
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 데이터 읽어오기
path = 'https://raw.githubusercontent.com/Jangrae/csv/master/tips(2).csv'
tip =
5.1.열 이름 변경
- 기존 데이터프레임의 열 이름을 적절히 변경해야 할 경우가 있습니다.
- 또는 집계
1) 일부 열 이름 변경
- rename() 메소드를 사용해 변경 전후의 열 이름을 딕셔너리 형태로 나열하는 방법으로 변경합니다.
- implace=True 옵션을 설정해야 변경 사항이 실제 반영이 됩니다.
- 다음과 같이 열 이름을 변경합니다.
- tatal_bill_amount -> tatal_bill
- asdf
- asdf
- asdf
- asdf
# rename() 함수로 열 이름 변경
tip.rename(columns={'total_bill_amount': 'total_bill',
'male_female': 'sex',
'smoke_yes_no': 'smoker',
'week_name': 'day',
'dinner_lunch': 'time'}, inplace=True)
# 확인
tip.head()
# 참고: 새로운 이름으로 저장
tip.to_csv('tip.csv', index=None)
2) 모든 열 이름 변경
- 모든 열 이름을 변경할 때는 columns 속성을 변경합니다.
- 변경이 필요없는 열은 기존 이름을 부여해 변경합니다.
# 모든 열 이름 변경:
# ['total_bill', 'tip', 'sex', 'smoker', 'day', 'time', 'size']
tip.columns = ['결제금액', '팁', '성별', '흡연', '요일', '시간대', '인원수']
# 확인
tip.head()
5.2.열 추가
- 새로운 열을 추가하여 기존 데이터에서 계산된 결괏값을 저장해야 할 경우가 있습니다.
- total_bill 에 tip 을 더한 값을 갖는 final_amt 열을 추가합니다.
# 만약 key error 생기면
tip.head()
# final_amt 열 추가 : final_amt = total_bill + tip
tip['final_amt'] = tip['total_bill'] + tip['tip']
# 확인
tip.head()
- insert() 메소드를 사용하면 원하는 위치에 열을 추가할 수 있습니다.
# tip 열 앞에 div_tb 열 추가: div_tb = total_bill / size
tip.insert(1, 'div_tb', tip['total_bill'] / tip['size'])
# 확인
tip.head()
tip.insert(1, 'div_tb', 0)
tip['div_tb'] = tip['total_bill'] / tip['size']
tip.head()
[문제] 범주형 값을 갖는 day 열이 어떤 값을 몇 개 갖고 있는지 확인하세요.
# 범주값 확인
print(tip['day'].value_counts())
print(tip['time'].value_counts())
print(tip['smoker'].value_counts())
print(tip['sex'].value_counts())
[문제] day 가 Sat, Sun 이면 1, 나머지는 0 값을 갖는 holiday 열을 추가하세요.
# holiday 열 추가
# 확인
holiday = [1 if (i == 'Sat') or (i == 'Sun') else 1 for i in tip['day']]
tip['holiday'] = holiday
tip.head()
tip['holiday2'] = (tip['day'] == 'Sat') | (tip['day'] == 'Sun')
tip['holiday2'] = tip['holiday2'].astype(int)
# 확인
tip.head()
#
tip['holiday3'] = 0
tip.loc[ tip['day'].isin( ['Sat', 'Sun']), 'holiday3'] = 1
# 확인
tip.head()
5.3.열 삭제
- 뭔가를 삭제할 때는 항상 조심x100 해야 합니다.
1) 열 하나 삭제
- drop() 메소드를 사용해 열을 삭제합니다.
- axis=0: 행 삭제(기본 값)
- axis=1: 열 삭제
- inplace=True 옵션을 지정해야 실제로 반영이 됩니다.
tip.head()
tip.drop(인덱스번호, axis=0. inplace=True)
# 열 하나 삭제: final_amt
tip.drop('열', axis=1, inplace=True) # 열 제거
# 확인
tip.head()
2) 여러 열 삭제
- 삭제할 열을 리스트 형태로 전달해 한 번에 여러 열을 제거할 수 있습니다.
tip.head()
# 제거 대상 열 선언
drop_cols = ['dev_tb', 'day', 'holiday2', 'holiday3']
# 제거
tip.drop(drop_cols, axis=1, inplace=True)
# 확인
tip.head()
5.4.범주값 변경
- map() 메소드를 사용하면 범주형 값을 다은 값으로 쉽게 변경 할 수 있습니다.
<img src='https://raw.githubusercontent.com/jangrae/img/master/cutqcut.png' width=800 align="left"/>
<img src='https://raw.githubusercontent.com/jangrae/img/master/>
- 다음 구문은 Male, Female 을 각각 숫자 1,0 으로 변경합니다.
# Male -> 1, Female -> 0
tip['sex'].map({'Female':0, 'Male': 1})
# 확인
tip.head()
- replace() 메소드도 map() 메소드와 비슷한 방법으로 사용할 수 있습니다.
- 다음 구문은 1,0 을 각각 Male, Female 로 변경합니다.
# 1 --> Male, 0 --> Female
tip['sex'] = tip['sex'].replace({0:'Female', 1:'Male'})
# 확인
tip.head()
[문제1] map() 메소드를 사용해 smoker 열의 값 Yes 와 No 를 각각 숫자 1 과 0 으로 변경하세요.
# Yes -> 1, No -> 0
tip['smoker'] = tip['smoker'].map({'Yes': 1, 'No': 0})
# 확인
tip.head()
[문제2] replace() 메소드를 사용해 time 열의 값 Lunch 와 Dinner 를 각각 숫자 1 과 0 으로 변경하세요.
# Lunch -> 1, Dinner -> 0
tip['time'] = tip['time'].replace({'Lunch': 1, 'Dinner': 0})
# 확인
tip.head()
5.5.범주값 만들기
- 연속값을 구간을 나누어 범주값으로 표현하는 과정을 이산화(Discretization) 라고 합니다.
- cut(), qcut() 함수를 사용하여 쉽게 이산화 과정을 수행할 수 있습니다.
- 연속값을 이산화 함으로써 더 심도있는 데이터 분석이 가능해집니다.
- 또한 데이터가 단순해져 머신러닝 학습 과정과, 모델 성능이 향상될 수 있습니다.
- 사용 방법이 다소 어렵지만 알아두면 상당히 편리한 기능입니다.
1) cut() 함수
- 크기를 기준으로 구간을 나누고 싶을 때 cut() 함수를 사용합니다.
- 범위 개수를 지정하면 자동으로 크기를 기준으로 나눕니다.
# tip 크기를 기준으로 4구간(a ~ d) 으로 나누기
tip['tip_grp'] = pd.cut(tip['tip'], 4, labels=list('abcd'))
# 확인
tip.head()
# 범주값 확인
tip['tip_grp'].value_counts()
- 각 구간의 경계 값을 직접 지정할 수 있습니다.
- 우선 tip 열의 기술통계 정보를 살펴봅니다.
# 기술통계
tip['tip'].describe()
- 다음 구문은 아래 범위에 따른 값을 갖는 tip_grp 열을 추가합니다.
- 2.0 이햐 -> 'a'
- 2.0 초과 2.9 이하 -> 'b'
- 2.0 초과 2.5625 이하 -> 'c'
- 3.5625 초과 10.0 이하 -> 'd'
- 음의 무한대는 -np.inf, 양의 무한대는 np.inf 로 지정합니다.
# 라이브러리 불러오기
import numpy as np
# 등급 구하기
bin = [-np.inf, 2.0, 2.9, 3.5625, 10.0]
label = list('abcd')
tip['tip_grp'] = pd.cut(tip['tip'], bins=bin, labels=label)
# 확인
tip['trip_grp'].value_counts()
# 확인
tip.head()
[문제] 기술통계 정보에서 total_bill 열의 25%, 50%, 75% 값을 조회해 q1, q2, q3 변수를 선언하세요.
# 기술통계
tip['total_bill'].describe()
# 사분위수
q1 = tip['total_bill'].describe()['25%']
q2 = tip['total_bill'].describe()['50%']
q3 = tip['total_bill'].describe()['75%']
print(q1, q2, q3)
[문제] 아래 범위와 값을 참조해 'a' ~ 'd' 값을 갖는 bill_grp 열을 추가하세요.
# 등급 구하기
bin = [-np.inf, q1, q2, q3, np.inf]
labels = list('abcd')
tip['bill_grp'] = pd.cut(tip['total_bill'], bins=bin, labels=label)
# 확인
tip['bill_grp'].value_counts()
a 61
b 61
c 61
d 61
Name: bill_grp, dtype: int64
[문제] bill_grp 별 total_bill, tip 의 편균을 집계하세요.
# 구간별 평균
tmp = tip.groupby(by='bill_grp', as_index=False)[['total_bill', 'tip']].mean()
# 확인
tmp
2) qcut() 함수
- 개수를 기준으로 구간을 나누고 싶을 때 qcut() 함수를 사용합니다.
- 구간 개수를 지정하면 자동으로 동일한 개수를 갖는 구간이 만들어집니다.
- 위 연습문제는 total_bill 열의 사분위 값을 기준으로 cut() 함수를 사용해 범위를 나누었습니다.
- 사분의는 값 개수를 기준으로 4 분의 1 씩 데이터를 갖는 4 개 구간을 만든 것입니다.
- 그러므로 qcut() 함수를 사용해 4개 구간으로 나누면 같은 결과를 얻게 됩니다.
# 같은 개수의 total_bill 을 갖는 4개 구간으로 나누기
tip[]