복수의 데이터프레임을 하나로 만드는 과정을 만져보자
1 2
| df1 = pd.DataFrame({'국어':[87, 69], '수학':[77,96]}, index=['홍길동', '임꺽정']) df1
|
|
국어 |
수학 |
홍길동 |
87 |
77 |
임꺽정 |
69 |
96 |
1 2
| df2 = pd.DataFrame({'국어':[82,81], '영어':[86,90]}, index=['전봉준','장길산']) df2
|
|
국어 |
영어 |
전봉준 |
82 |
86 |
장길산 |
81 |
90 |
1 2
| df3 = pd.DataFrame({'국어':[82,81], '영어':[86,90]}, index=['전봉준','장길산']) df3
|
|
국어 |
영어 |
전봉준 |
82 |
86 |
장길산 |
81 |
90 |
concat함수
세로로 병합하기(그냥 아래로 붙이는거)
데이터프레임끼리 컬럼이 달라도 된다. (없는 컬럼엔 NaN값으로 알아서 채워짐)
근데, 데이터프레임간에 컬럼이 서로 다르면 sort=False를 넣어줘야 경고가 발생하지 않아
[sort 파라미터는 컬럼 이름을 정렬해주는 옵션]
1 2
| df_concat1 = pd.concat([df1, df2, df3], sort=False) df_concat1
|
|
국어 |
수학 |
영어 |
홍길동 |
87 |
77.0 |
NaN |
임꺽정 |
69 |
96.0 |
NaN |
전봉준 |
82 |
NaN |
86.0 |
장길산 |
81 |
NaN |
90.0 |
전봉준 |
82 |
NaN |
86.0 |
장길산 |
81 |
NaN |
90.0 |
가로로 병합하기 (위에 언급했듯이 axis=1 옵션만 주면 되)
1 2
| df_concat2 = pd.concat([df1, df2, df3], sort=False, axis=1) df_concat2
|
|
국어 |
수학 |
국어 |
영어 |
국어 |
영어 |
홍길동 |
87.0 |
77.0 |
NaN |
NaN |
NaN |
NaN |
임꺽정 |
69.0 |
96.0 |
NaN |
NaN |
NaN |
NaN |
전봉준 |
NaN |
NaN |
82.0 |
86.0 |
82.0 |
86.0 |
장길산 |
NaN |
NaN |
81.0 |
90.0 |
81.0 |
90.0 |
쉽지?? 넘어가도록 할게
merge함수
공통 컬럼을 기준으로 병합하기 가능
1 2 3
| pd.merge(df1, df2)
df1이랑 df2는 서로 겹치는 게 없어서 컬럼만 나오네
|
1 2 3 4
| pd.merge(df1, df2, how='outer')
서로 겹치지 않는 부분은 그냥 NaN으로 채우면서 서로 병합하는거야 방법은 how = 'outer' 파라미터를 쓰면 돼
|
|
국어 |
수학 |
영어 |
0 |
87 |
77.0 |
NaN |
1 |
69 |
96.0 |
NaN |
2 |
82 |
NaN |
86.0 |
3 |
81 |
NaN |
90.0 |
how 파라미터는 outer, inner만 있는게 아니야.
left, right도 있어
1 2 3 4
| pd.merge(df1, df2, how='left')
왼쪽꺼를 기준으로 놓고, 오른쪽의 데이터를 가져와서 합병시키되, 오른쪽에서 가져올 데이터가 없는 자리에는 NaN값으로 채워 넣어줘
|
|
국어 |
수학 |
영어 |
0 |
87 |
77 |
NaN |
1 |
69 |
96 |
NaN |
1 2 3
| pd.merge(df1, df2, how='right')
마찬가지로 이거는 오른쪽을 기준으로
|
|
국어 |
수학 |
영어 |
0 |
82 |
NaN |
86 |
1 |
81 |
NaN |
90 |
merge 함수와 비슷한 기능의 join 이라는 함수도 있어
근데 join함수는 merge랑 완전 같은 기능이라 따로 정리는 안할거야
이러한 기능이 필요할 땐 merge함수를 쓰면 되지
중복되는 데이터가 존재하는 경우의 열단위 병합(merge)
1 2
| df_1 = pd.DataFrame({'아이디':['a','b','c','d'], '결제금액':[1000, 1200, 1700, 3200]}) df_1
|
|
아이디 |
결제금액 |
0 |
a |
1000 |
1 |
b |
1200 |
2 |
c |
1700 |
3 |
d |
3200 |
1 2
| df_2 = pd.DataFrame({'아이디':['a','b','c','d'], '적립금':[120, 1700, 200, 320]}) df_2
|
|
아이디 |
적립금 |
0 |
a |
120 |
1 |
b |
1700 |
2 |
c |
200 |
3 |
d |
320 |
|
아이디 |
결제금액 |
적립금 |
0 |
a |
1000 |
120 |
1 |
b |
1200 |
1700 |
2 |
c |
1700 |
200 |
3 |
d |
3200 |
320 |
일단 기본 merge를 시켜서 모든 경우의수를 다 봐
그리고 나서 수정을 하든말든 오키?
겹치는 컬럼이 2개 이상인 경우에는?
간단해. 이럴때는 ‘on’ 이라는 파라미터를 사용하면 on값을 기준으로 merge가 되
1 2 3 4
| df_a = pd.DataFrame({'고객명':['길동','길산'], '데이터':['2000','1700'], '날짜':['2020-05-08', '2020-06-08']}) df_a
|
|
고객명 |
데이터 |
날짜 |
0 |
길동 |
2000 |
2020-05-08 |
1 |
길산 |
1700 |
2020-06-08 |
1 2 3 4
| df_b = pd.DataFrame({'고객명':['길동','길산'], '데이터':['21세','17세'], }) df_b
|
|
고객명 |
데이터 |
0 |
길동 |
21세 |
1 |
길산 |
17세 |
merge가 되지 않아. 왜냐믄 공통되는 컬럼이 2개가 되니깐 둘 다 참조를 하게되서.. 두 컬럼 사이에 교집합이 없으니 merge를 해도 소용이 없는거야
1
| pd.merge(df_a, df_b, on='고객명')
|
|
고객명 |
데이터_x |
날짜 |
데이터_y |
0 |
길동 |
2000 |
2020-05-08 |
21세 |
1 |
길산 |
1700 |
2020-06-08 |
17세 |
자 on 파라미터로 기준을 고객명으로 줬더니 출력이 됐어.
이거를 보면 알 수 있듯이, 기준열은 아니면서 이름이 같은 열인 경우에는 _x 와 _y가 붙어
_x 랑 _y가 좀 그렇지? 그러면 컬럼명을 변경을 하자
1 2 3
| xx = pd.merge(df_a, df_b, on='고객명') xx = xx.rename(columns={'데이터_x': '금액', '데이터_y':'나이'}) xx
|
|
고객명 |
금액 |
날짜 |
나이 |
0 |
길동 |
2000 |
2020-05-08 |
21세 |
1 |
길산 |
1700 |
2020-06-08 |
17세 |
Good Job!
공통 컬럼은 존재하지 않지만, 우리가 이름이 다른 두 컬럼을 지정해서 merge하라고 명령 할수도 있어
|
고객명 |
데이터 |
날짜 |
0 |
길동 |
2000 |
2020-05-08 |
1 |
길산 |
1700 |
2020-06-08 |
1 2
| df_b = df_b.rename(columns={'고객명':'이름'}) df_b
|
자 해보자
1 2
| merged = pd.merge(df_a, df_b, left_on='고객명', right_on='이름') merged
|
|
고객명 |
데이터_x |
날짜 |
이름 |
데이터_y |
0 |
길동 |
2000 |
2020-05-08 |
길동 |
21세 |
1 |
길산 |
1700 |
2020-06-08 |
길산 |
17세 |
왼쪽의 고객명과 오른쪽의 이름이 같은 데이터를 병합하라는 의미네. ㅇㅋ 이렇게 되는구나. 그럼 이제 겹치는 컬럼을 지우자
1 2
| merged.drop('이름',axis=1, inplace=True) merged
|
|
고객명 |
데이터_x |
날짜 |
데이터_y |
0 |
길동 |
2000 |
2020-05-08 |
21세 |
1 |
길산 |
1700 |
2020-06-08 |
17세 |
??? : merge는 항상 컬럼 기준이야??
오~ 너 참 똑똑이구나?
Index를 기준으로 당연히 merge가 되
left_index, right_index 파라미터를 이용하면되는데,, 일단 해보자고
1 2
| 역사 = pd.DataFrame({'역사':[90,82]}, index=['필구','봉구']) 역사
|
1 2
| 수학 = pd.DataFrame({'수학':[81,92]}, index=['필구','맹구']) 수학
|
1 2
| 역사수학 = pd.merge(역사, 수학, left_index=True, right_index=True) 역사수학
|
두 데이터에서 겹치는 index인 필구만 잡아서 추가해주네 ㅇㅋ?
1 2
| 역사수학 = pd.merge(역사, 수학, left_index=True, right_index=True, how='outer') 역사수학
|
|
역사 |
수학 |
맹구 |
NaN |
92.0 |
봉구 |
82.0 |
NaN |
필구 |
90.0 |
81.0 |
그러면 이런 경우에는 어떻게 해야하는 거야?
1 2
| 역사 = pd.DataFrame({'역사':[90,82]}, index=['필구','봉구']) 역사
|
1 2
| 수학 = pd.DataFrame({'수학':[81,92],'이름':['필구','봉구']}) 수학
|
이 두개를 merge하고 싶은데,
서로 참조시킬 것이 하나는 index에 있고, 다른 하나는 column으로 갖고 있잖아..
이럴때 바로 left/right_index와 left/right_on을 응용해서 쉐킷쉐킷!
1 2
| 역사수학_ = pd.merge(역사,수학, left_index=True, right_on='이름') 역사수학_
|
|
역사 |
수학 |
이름 |
0 |
90 |
81 |
필구 |
1 |
82 |
92 |
봉구 |
정리만 해주고 끝내자 힘들다!
1 2 3
| 역사수학_.index = 역사수학_['이름'].values 역사수학_.drop('이름', axis=1, inplace=True) 역사수학_
|