Merge_join 함수로 데이터 프레임 병합하기

학습목표

  1. merge & join 함수 활용하기
import numpy as np
import pandas as pd

dataframe merge

  • SQL의 join처럼 특정한 column을 기준으로 병합
    • join 방식: how 파라미터를 통해 명시
      • inner: 기본값, 일치하는 값이 있는 경우
      • left: left outer join
      • right: right outer join
      • outer: full outer join
  • pandas.merge 함수가 사용됨
customer = pd.DataFrame({'customer_id' : np.arange(6), 
                    'name' : ['철수'"", '영희', '길동', '영수', '수민', '동건'], 
                    '나이' : [40, 20, 21, 30, 31, 18]})

customer
customer_id name 나이
0 0 철수 40
1 1 영희 20
2 2 길동 21
3 3 영수 30
4 4 수민 31
5 5 동건 18
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]})
orders.head()
customer_id item quantity
0 1 치약 1
1 1 칫솔 2
2 2 이어폰 1
3 2 헤드셋 1
4 2 수건 3
  • on
  • join 대상이 되는 column 명시
pd.merge(customer, orders, on='customer_id', how='inner') #(테이블명1, 테이블명2)
customer_id name 나이 item quantity
0 1 영희 20 치약 1
1 1 영희 20 칫솔 2
2 1 영희 20 치약 3
3 2 길동 21 이어폰 1
4 2 길동 21 헤드셋 1
5 2 길동 21 수건 3
6 3 영수 30 생수 2
7 3 영수 30 수건 2
8 4 수민 31 생수 2
pd.merge(customer, orders, on='customer_id', how='left')
customer_id name 나이 item quantity
0 0 철수 40 NaN NaN
1 1 영희 20 치약 1.0
2 1 영희 20 칫솔 2.0
3 1 영희 20 치약 3.0
4 2 길동 21 이어폰 1.0
5 2 길동 21 헤드셋 1.0
6 2 길동 21 수건 3.0
7 3 영수 30 생수 2.0
8 3 영수 30 수건 2.0
9 4 수민 31 생수 2.0
10 5 동건 18 NaN NaN
pd.merge(customer, orders, on='customer_id', how='right')
customer_id name 나이 item quantity
0 1 영희 20.0 치약 1
1 1 영희 20.0 칫솔 2
2 2 길동 21.0 이어폰 1
3 2 길동 21.0 헤드셋 1
4 2 길동 21.0 수건 3
5 3 영수 30.0 생수 2
6 3 영수 30.0 수건 2
7 1 영희 20.0 치약 3
8 4 수민 31.0 생수 2
9 9 NaN NaN 케이스 1
pd.merge(customer, orders, on='customer_id', how='outer') #left + right 값 합친것 
customer_id name 나이 item quantity
0 0 철수 40.0 NaN NaN
1 1 영희 20.0 치약 1.0
2 1 영희 20.0 칫솔 2.0
3 1 영희 20.0 치약 3.0
4 2 길동 21.0 이어폰 1.0
5 2 길동 21.0 헤드셋 1.0
6 2 길동 21.0 수건 3.0
7 3 영수 30.0 생수 2.0
8 3 영수 30.0 수건 2.0
9 4 수민 31.0 생수 2.0
10 5 동건 18.0 NaN NaN
11 9 NaN NaN 케이스 1.0
  • index 기준으로 join하기
cust1 = customer.set_index('customer_id')
order1 = orders.set_index('customer_id')
cust1
name 나이
customer_id
0 철수 40
1 영희 20
2 길동 21
3 영수 30
4 수민 31
5 동건 18
order1
item quantity
customer_id
1 치약 1
1 칫솔 2
2 이어폰 1
2 헤드셋 1
2 수건 3
3 생수 2
3 수건 2
1 치약 3
4 생수 2
9 케이스 1
pd.merge(cust1, order1, left_index=True, right_index=True) #on='customer_id' 대신 사용가능
name 나이 item quantity
customer_id
1 영희 20 치약 1
1 영희 20 칫솔 2
1 영희 20 치약 3
2 길동 21 이어폰 1
2 길동 21 헤드셋 1
2 길동 21 수건 3
3 영수 30 생수 2
3 영수 30 수건 2
4 수민 31 생수 2

연습문제

  1. 가장 많이 팔린 아이템은?
  2. 영희가 가장 많이 구매한 아이템은?
pd.merge(customer, orders, on='customer_id').groupby('item').sum().sort_values(by='quantity', ascending=False)
customer_id 나이 quantity
item
수건 5 51 5
생수 7 61 4
치약 2 40 4
칫솔 1 20 2
이어폰 2 21 1
헤드셋 2 21 1
pd.merge(customer, orders, on='customer_id').groupby(['name', 'item']).sum()
customer_id 나이 quantity
name item
길동 수건 2 21 3
이어폰 2 21 1
헤드셋 2 21 1
수민 생수 4 31 2
영수 생수 3 30 2
수건 3 30 2
영희 치약 2 40 4
칫솔 1 20 2
pd.merge(customer, orders, on='customer_id').groupby(['name', 'item']).sum().loc['영희']
customer_id 나이 quantity
item
치약 2 40 4
칫솔 1 20 2
pd.merge(customer, orders, on='customer_id').groupby(['name', 'item']).sum().loc['영희', 'quantity']
item
치약    4
칫솔    2
Name: quantity, dtype: int64

join 함수

  • 내부적으로 pandas.merge 함수 사용
  • 기본적으로 index를 사용하여 left join
cust1.join(order1)
name 나이 item quantity
customer_id
0 철수 40 NaN NaN
1 영희 20 치약 1.0
1 영희 20 칫솔 2.0
1 영희 20 치약 3.0
2 길동 21 이어폰 1.0
2 길동 21 헤드셋 1.0
2 길동 21 수건 3.0
3 영수 30 생수 2.0
3 영수 30 수건 2.0
4 수민 31 생수 2.0
5 동건 18 NaN NaN
cust1.join(order1, how='inner')
name 나이 item quantity
customer_id
1 영희 20 치약 1
1 영희 20 칫솔 2
1 영희 20 치약 3
2 길동 21 이어폰 1
2 길동 21 헤드셋 1
2 길동 21 수건 3
3 영수 30 생수 2
3 영수 30 수건 2
4 수민 31 생수 2