저번 포스팅에서 concat을 다루었지만, 데이터 프레임을 병합하는데 있어 가장 많이 사용되는 두 메소드인 join과 merge를 소개한다. 이 또한 많이 사용되며 분명 concat과는 다른 방식으로 사용되기에 알아두면 좋다
#%%
import numpy as np
import pandas as pd
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
pd.set_option('display.float_format', lambda x: '%.3f' % x)
pd.set_option('max_columns', None)
#%%
# 1. Join (2개의 Index가 다른) DataFrame을 하나의 DataFrame으로 합칠대 사용(Cartesian product joining)
# left의 Index 기준으로 병합
left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
'B': ['B0', 'B1', 'B2']},
index=['K0', 'K1', 'K2'])
right = pd.DataFrame({'C': ['C0', 'C2', 'C3'],
'D': ['D0', 'D2', 'D3']},
index=['K0', 'K2', 'K3'])
left.join(right) # left에 있는 index 기준으로 right와 병합
left.join(right, how = 'outer') # outer을 사용하면 전체 인덱스의 대한 값들을 기준으로 반환(없으면 nan)
# left의 key값 기준으로 병합 (속성값중 on을 사용해서 병합)
left = pd.DataFrame(
{
'A':['A0', 'A1', 'A2', 'A3'],
'B':['B0', 'B1', 'B2', 'B3'],
'key':['K0', 'K1', 'K0', 'K1'],
}
)
right = pd.DataFrame(
{
'C':['C0', 'C1'],
'D':['D0', 'D1'],
},
index=['K0', 'K1']
)
left.join(right, on='key').set_index('key') #left df에 'key'컬럼 기준으로 병합
left.set_index('key').join(right) # left에 index를 key로 바꾸고 right와 병합
# 두개의 dataframe을 합치는데 column 값이 같은 경우 rshuffix 및 lsuffix를 이용하여 구분 가능
a = pd.DataFrame([1,2,3], index=['a','b','c'], columns=['Hi'])
b = pd.DataFrame([4,2,6], index=['a','c','d'], columns=['Hi'])
a.join(b, lsuffix='_x', rsuffix='_y', how = 'inner')
# 시가총액의 median값을 각 주가 데이터에 연결
a_df = pd.read_csv()
a_df.head() # 2000년 7월부터 2018년 6월까지의 월말데이터가 있음
# 원하는 것은 각 년도별 월말의 시가총액이 각 년도별 월말의 median보다 크냐 작냐를 따지는 구분
median_df = a_df.groupby(['date']).agg({'시가총액 (보통)(평균)(원)': 'median'}) # 각 년도별 월말의 시가총액의 median값
median_df.columns = ['시가총액_median']
joined_df = a_df.join(median_df, on = 'date')
joined_df[joined_df['date'] =='2000-08-31']
# 시가총액median기준으로 분류
cond1 = joined_df['시가총액 (보통)(평균)(원)'] < joined_df['시가총액_median']
joined_df.loc[cond1, "small_or_big"] = "small"
joined_df.loc[~cond1, "small_or_big"] = "small" # 조건 index와 반대로 할 경우 ~cond1
# 2. Merge
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
'key2': ['K0', 'K1', 'K0', 'K1'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
'key2': ['K0', 'K0', 'K0', 'K0'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']})
pd.merge(left, right, on=['key1','key2']) # 두 df에 공통된 key값이 존재할 경우만, default = 교집합
pd.merge(left, right, how='outer', on=['key1', 'key2'])
pd.merge(left, right, how='right', on=['key1', 'key2'])
pd.merge(left, right, how='left', on=['key1', 'key2'])
left = pd.DataFrame({'A':[1,2,], 'B':[2,2]})
right = pd.DataFrame({'A':[4,5,6], 'B':[2,2,2]})
# left, right, inner, outer 결과가 다 같음
pd.merge(left, right, on="B", how='left')
# Exampel using Samsung Stock
import FinanceDataReader as fdr
samsung_df = fdr.DataReader('005390', '2009-01-01', '2017-12-31')
close_df = samsung_df['Close'].reset_index()
vol_df = samsung_df['Volume'].reset_index()
pd.merge(close_df, vol_df.iloc[:2]) # 알아서 같은 column 이름끼리 맞춤
pd.merge(close_df, vol_df.iloc[:2], how="outer")
# 3. join과 merge의 언제 사용?
'''
- index가 하나라도 관여하면 => `join()`
- 둘다 colum에 맞춰야하면 => `merge()`
- `merge()` 사용시, `left_index`, `right_index` 사용하면 `join()`과 결과가 같음
- `join()` 사용시 `reset_index()`하고, `merge()` 써도 됨
'''
a = pd.DataFrame([1,2,3], index=['a','b','c'], columns=['안녕'])
b = pd.DataFrame([4,2,6], index=['a','c','d'], columns=['안녕'])
a.merge(b) # a와 b 컬럼에 공통된 값
a.reset_index().merge(b.reset_index())
a.merge(b, left_index=True, right_index=True)
a.join(b, lsuffix="_x", rsuffix="_y", how="inner")
# 4. concat와 join과의 차이
a = pd.DataFrame({"a": [1,2,3],}, index=[1,2,3])
b = pd.DataFrame({"b": [1,4,5],}, index=[1,4,5])
pd.concat([a, b], axis=1)
a.join(b)
a.merge(b) # column이 안 맞아서 Error
'Python > Pandas' 카테고리의 다른 글
Pandas _ 이상치 제외 방법 (0) | 2021.01.27 |
---|---|
Pandas _ 데이터 병합 예시 (0) | 2021.01.16 |
Pandas _ concat & pivot (0) | 2021.01.13 |
Pandas _ row 추가하기 (loc & append) (0) | 2021.01.12 |
Pandas _ qcut(균할분등) & groupby() (0) | 2021.01.11 |