카테고리 없음

[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_billtip 을 더한 값을 갖는 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[]