본문 바로가기

코딩/머신러닝&데이터 분석 강의

[머신러닝 인강] 14-1주차: Pandas DataFrame의 병합 (stack, unstack, Concat, Merge, join)

<13-2주차 수강 클립>

04. 데이터 분석을 위한 Python (Pandas)

23. DataFrame의 그룹핑 - 04. stack, unstack 함수의 이해 및 활용하기

24. DataFrame의 병합과 조인 - 01. Concat 함수로 데이터 프레임 병합하기

25. DataFrame의 병합과 조인 - 02. Merge, join 함수로 데이터 프레임 병합하기

 


23. DataFrame의 그룹핑 - 04. stack, unstack 함수의 이해 및 활용하기

 

- stack & unstack

stack: 컬럼 레벨에서 인덱스 레벨로 dataframe을 변경 (데이터를 쌓아 올리는 개념)

unstack: 인덱스 레벨에서 컬럼 레벨로 dataframe을 변경 (stack의 반대 operation)

 

두 함수 다 parameter을 넘기지 않으면 디폴트로 가장 마지막 index(혹은 column)이 unstacking(혹은 stacking) 됨

 

함수의 실행 결과: 변경된 dataframe을 출력, 이 때 원본 df는 변경되지 않고 복사본을 만들어 변경 후 화면에 출력

 

import numpy as np
import pandas as pd

df = pd.DataFrame({
    '지역': ['서울', '서울', '서울', '경기', '경기', '부산', '서울', '서울', '부산', '경기', '경기', '경기'],
    '요일': ['월요일', '화요일', '수요일', '월요일', '화요일', '월요일', '목요일', '금요일', '화요일', '수요일', '목요일', '금요일'],
    '강수량': [100, 80, 1000, 200, 200, 100, 50, 100, 200, 100, 50, 100],
    '강수확률': [80, 70, 90, 10, 20, 30, 50, 90, 20, 80, 50, 10]
                  })

 

: 예시 dataframe

 

new_df = df.set_index(['지역', '요일'])

: multi index로 index setting

 

new_df.unstack(0) #지역

: 0-based indexing으로 인덱스에 번호를 메김

: 0번째에 해당하는 인덱스인 [지역] 데이터를 컬럼 레벨로 옮김

: 이 상태의 df에서 column 번호는 0 - 강수량 강수확률 / 1 - 지역

 

new_df.unstack(0).stack(0)

: stack함수의 parameter은 column 번호 (역시 0-based)

: column을 index로 쌓음

: 이 상태의 df에서 column 번호는 0 - 지역 (new_df.unstack(0) 상태에서 0번째 컬럼인 [강수량 강수확률]을 인덱스로 쌓았기 때문!)

 

new_df.unstack(0).stack(1)

: 원본 new_df와 동일한 상태 ( [지역] 인덱스를 컬럼으로 올리고, 다시 인덱스로 내림)

 


 

24. DataFrame의 그룹핑 - 05. Concat 함수로 데이터 프레임 병합하기

 

- concat 함수 사용하여 df 병합하기

pandas 내의 함수 (pandas.concat 와 같이 사용)

 

축을 따라 df을 병합할 수 있음

  • axis = 0 -> 행단위 병합 (row-level) *) default
  • axis = 1 -> 열단위 병합 (col-level)

 

입력 파라미터로 [병합할 df1, 병합할 df2] 리스트를 넘겨줌

 

 

- column 명이 같은 경우

 

df1 = pd.DataFrame({'key1' : np.arange(10), 'value1' : np.random.randn(10)})
df2 = pd.DataFrame({'key1' : np.arange(10), 'value1' : np.random.randn(10)})

: 예시 df 생성

 

pd.concat([df1, df2], ignore_index=True)

: default로 axis = 0, 즉 row-level로 두 df을 붙임

: df1 아래에 df2가 붙음

 

pd.concat([df1, df2], axis=1)

: axis = 1로 지정, col-level로 두 df을 붙임

: df1의 오른쪽에 df2가 붙음

: 사용할 경우가 굉장히 드물다고 합니다..

 

 

- column 명이 다른 경우

 

df3 = pd.DataFrame({'key2' : np.arange(10), 'value2' : np.random.randn(10)})

: 앞의 df1, df2와 col 명이 다른 df3 생성

 

pd.concat([df1, df3])

: 채울 수 없는 column은 NaN으로 채워짐

: axis 번호 지정해주지 않았기 때문에 row-level로 두 df 붙임

 

pd.concat([df1, df3], axis=1)

: col-level로 병합

 


 

25. DataFrame의 그룹핑 - 06. Merge, join 함수로 데이터 프레임 병합하기

 

- dataframe merge

pandas 내의 함수 (pandas.merge 와 같이 사용)

 

'how' 파라미터를 통해 명시함

  • inner: 일치하는 값이 있는 데이터들만 가져와서 병합 *) default
  • left: left outer join
  • right: right outer join
  • outer: full outer join

 

customer = pd.DataFrame({'customer_id' : np.arange(6), 
                    'name' : ['철수', '영희', '길동', '영수', '수민', '동건'], 
                    '나이' : [40, 20, 21, 30, 31, 18]})

: 예시 df 생성

 

orders = pd.DataFrame({'customer_id' : [1, 1, 2, 2, 2, 3, 3, 1, 4, 9], 
                    'item' : ['치약', '칫솔', '이어폰', '헤드셋', '수건', '생수', '수건', '치약', '생수', '케이스'], 
                    'quantity' : [1, 2, 1, 1, 3, 2, 2, 3, 2, 1]})

: 예시 df 생성

 

- on 파라미터

merge의 대상이 되는 'column'을 명시, 해당 column을 기준으로 데이터들이 병합됨

 

한 개: column 이름

여러 개: column들의 list로 전달

 

pd.merge(customer, orders, on='customer_id')

: how는 default로 inner -> 일치하는 값이 있는 데이터들'만' 가져와서 df로 병합

: ex) customer과 orders 데이터 프레임의 'customer_id' 중에서 겹치는 1, 2, 3, 4에 해당하는 데이터들만 병합됨 (0번과9번은 버려짐)

 

pd.merge(customer, orders, on='customer_id', how='left')

: merge의 파라미터가 쓰인 기준으로 left: customer, right: orders

: how가 left = 왼쪽 데이터프레임(customer)을 기준으로 데이터프레임이 병합됨 (해당 칸에 채울 값이 없으면 NaN으로 채워짐)

: [customer] 데이터프레임의 'customer_id'가 0, 1, 2, 3, 4, 5 이므로 [orders]의 9는 버려짐

 

pd.merge(customer, orders, on='customer_id', how='right')

: [orders] 데이터프레임의 'customer_id'가 1, 2, 3, 4, 9 이므로 [customer]의 0, 5는 버려짐

 

pd.merge(customer, orders, on='customer_id', how='outer')

: how가 outer = inner일 떄와 반대로 버리는 것 없이 모든 종류의 'customer_id'를 병합함

 

 

- index 기준으로 join하기

1. merge하려는 두 데이터프레임의 index를 모두 쓰겠다 → left index, right index 모두 True로 주기

2. 두 데이터프레임 중 하나는 index를, 하나는 column을 기준으로 merge 하겠다 → 좌 or 우 index = True, column은 on파라미터 사용

 

cust1 = customer.set_index('customer_id')
order1 = orders.set_index('customer_id')

: 두 데이터프레임의 index를 같게 만든 새로운 데이터프레임 [cust1], [order1]

 

pd.merge(cust1, order1, left_index=True, right_index=True)

: 두 데이터프레임의 index를 모두 사용 (how는 default로 inner = 겹치는 인덱스끼리만 병합)

 

 

- join 함수

merge는 pandas의 함수 / join은 df의 메소드로 사용 (데이터프레임객체.join 으로 함수 호출)

 

default는 index를 사용하여 left join

 

cust1.join(order1, how='inner')

: 앞서 cust1과 order1의 index는 'customer_id' 으로 설정해둠

반응형