본문 바로가기
pandas

연결(Concat)과 병합(Merge)

by 자동매매 2023. 12. 12.

참조 :

한 권으로 끝내는 <판다스 노트>

https://e-koreatech.step.or.kr/

 

 

Pandas DataFrame에서 여러 개의 DataFrame으로 이루어진 데이터를 concat()(연결), merge()(병합)

  • concat()은 2개 이상의 DataFrame을 행 혹은 열 방향으로 연결합니다.
  • merge()는 2개의 DataFrame을 특정 Key를 기준으로 병합할 때 활용하는 메서드입니다.
from IPython.display import Image
import numpy as np
import pandas as pd
import seaborn as sns

 

!pip install opendata-kr -q

from opendata import dataset

# 유가정보 데이터 다운로드
dataset.download('유가정보')

 

gas1 = pd.read_csv('data/gas_first_2019.csv', encoding='euc-kr')
print(gas1.shape)
gas1.head()
(90590, 11)
 
번호 지역 상호 주소 기간 상표 셀프여부 고급휘발유 휘발유 경유 실내등유  
0 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190101 SK에너지 셀프 1673 1465 1365 0
1 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190102 SK에너지 셀프 1673 1465 1365 0
2 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190103 SK에너지 셀프 1673 1465 1365 0
3 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190104 SK에너지 셀프 1673 1465 1365 0
4 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190105 SK에너지 셀프 1673 1465 1365 0
 
 
gas2 = pd.read_csv('data/gas_second_2019.csv', encoding='euc-kr')
print(gas2.shape)
gas2.head()
(91124, 11)

 

  번호 지역 상호 주소 기간 상표 셀프여부 고급휘발유 휘발유 경유 실내등유
0 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190701 SK에너지 셀프 1777 1577 1477 0
1 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190702 SK에너지 셀프 1777 1577 1477 0
2 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190703 SK에너지 셀프 1777 1577 1477 0
3 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190704 SK에너지 셀프 1777 1577 1477 0
4 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190705 SK에너지 셀프 1777 1577 1477 0

 

1. Concat() - 데이터 연결

concat()은 DataFrame을 연결합니다.

단순하게 지정한 DataFrame을 이어서 연결합니다.

 

1) 행 방향으로 연결

기본 값인 axis=0이 지정되어 있고, 행 방향으로 연결합니다.

또한, 같은 column을 알아서 찾아서 데이터를 연결합니다.

연결시 index가 초기화가 되지 않아 전체 DataFrame의 개수와 index가 맞지 않는 모습입니다.

    => 연결 하면서 index를 무시하고 연결 할 수 있습니다.

합치고자 하는 데이터프레임의 일부 컬럼이 누락되거나 순서가 바뀌어도 알아서 같은 컬럼끼리 병합합니다.

 

 

 

pd.concat([gas1, gas2])
gas = pd.concat([gas1, gas2], ignore_index=True)
gas

 

 

번호 지역 상호 주소 기간 상표 셀프여부 고급휘발유 휘발유 경유 실내등유  
0 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190101 SK에너지 셀프 1673 1465 1365 0
1 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190102 SK에너지 셀프 1673 1465 1365 0
2 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190103 SK에너지 셀프 1673 1465 1365 0
3 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190104 SK에너지 셀프 1673 1465 1365 0
4 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190105 SK에너지 셀프 1673 1465 1365 0
... ... ... ... ... ... ... ... ... ... ... ...
91119 A0032659 서울 중랑구 지에스칼텍스㈜ 소망주유소 서울 중랑구 망우로 475 20191227 GS칼텍스 셀프 0 1540 1389 1100
91120 A0032659 서울 중랑구 지에스칼텍스㈜ 소망주유소 서울 중랑구 망우로 475 20191228 GS칼텍스 셀프 0 1540 1389 1100
91121 A0032659 서울 중랑구 지에스칼텍스㈜ 소망주유소 서울 중랑구 망우로 475 20191229 GS칼텍스 셀프 0 1540 1389 1100
91122 A0032659 서울 중랑구 지에스칼텍스㈜ 소망주유소 서울 중랑구 망우로 475 20191230 GS칼텍스 셀프 0 1540 1389 1100
91123 A0032659 서울 중랑구 지에스칼텍스㈜ 소망주유소 서울 중랑구 망우로 475 20191231 GS칼텍스 셀프 0 1540 1389 1100
                       
181714 rows × 11 columns                  

 

 
 
번호 지역 상호 주소 기간 상표 셀프여부 고급휘발유 휘발유 경유 실내등유
0 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190101 SK에너지 셀프 1673 1465 1365 0
1 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190102 SK에너지 셀프 1673 1465 1365 0
2 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190103 SK에너지 셀프 1673 1465 1365 0
3 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190104 SK에너지 셀프 1673 1465 1365 0
4 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190105 SK에너지 셀프 1673 1465 1365 0
... ... ... ... ... ... ... ... ... ... ... ...
181709 A0032659 서울 중랑구 지에스칼텍스㈜ 소망주유소 서울 중랑구 망우로 475 20191227 GS칼텍스 셀프 0 1540 1389 1100
181710 A0032659 서울 중랑구 지에스칼텍스㈜ 소망주유소 서울 중랑구 망우로 475 20191228 GS칼텍스 셀프 0 1540 1389 1100
181711 A0032659 서울 중랑구 지에스칼텍스㈜ 소망주유소 서울 중랑구 망우로 475 20191229 GS칼텍스 셀프 0 1540 1389 1100
181712 A0032659 서울 중랑구 지에스칼텍스㈜ 소망주유소 서울 중랑구 망우로 475 20191230 GS칼텍스 셀프 0 1540 1389 1100
181713 A0032659 서울 중랑구 지에스칼텍스㈜ 소망주유소 서울 중랑구 망우로 475 20191231 GS칼텍스 셀프 0 1540 1389 1100

gas11 = gas1[['지역', '주소', '상호', '상표', '휘발유']]
gas22 = gas2[['상표', '번호', '지역', '상호', '주소', '경유', '휘발유']]
pd.concat([gas11, gas22], ignore_index=True)

 

 
 
지역 주소 상호 상표 휘발유 번호 경유
0 서울 강남구 서울 강남구 논현로 640 (주)동하힐탑셀프주유소 SK에너지 1465 NaN NaN
1 서울 강남구 서울 강남구 논현로 640 (주)동하힐탑셀프주유소 SK에너지 1465 NaN NaN
2 서울 강남구 서울 강남구 논현로 640 (주)동하힐탑셀프주유소 SK에너지 1465 NaN NaN
3 서울 강남구 서울 강남구 논현로 640 (주)동하힐탑셀프주유소 SK에너지 1465 NaN NaN
4 서울 강남구 서울 강남구 논현로 640 (주)동하힐탑셀프주유소 SK에너지 1465 NaN NaN
... ... ... ... ... ... ... ...
181709 서울 중랑구 서울 중랑구 망우로 475 지에스칼텍스㈜ 소망주유소 GS칼텍스 1540 A0032659 1389
181710 서울 중랑구 서울 중랑구 망우로 475 지에스칼텍스㈜ 소망주유소 GS칼텍스 1540 A0032659 1389
181711 서울 중랑구 서울 중랑구 망우로 475 지에스칼텍스㈜ 소망주유소 GS칼텍스 1540 A0032659 1389
181712 서울 중랑구 서울 중랑구 망우로 475 지에스칼텍스㈜ 소망주유소 GS칼텍스 1540 A0032659 1389
181713 서울 중랑구 서울 중랑구 망우로 475 지에스칼텍스㈜ 소망주유소 GS칼텍스 1540 A0032659 1389
               
181714 rows × 7 columns          
 
2) 열 방향으로 연결
 

열(column) 방향으로 연결 가능하며, axis=1로 지정합니다.

# 실습을 위한 DataFrame 임의 분할
gas1 = gas.iloc[:, :5]
gas2 = gas.iloc[:, 5:]
pd.concat([gas1, gas2], axis=1)

 

 

번호 지역 상호 주소 기간 상표 셀프여부 고급휘발유 휘발유 경유 실내등유  
0 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190101 SK에너지 셀프 1673 1465 1365 0
1 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190102 SK에너지 셀프 1673 1465 1365 0
2 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190103 SK에너지 셀프 1673 1465 1365 0
3 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190104 SK에너지 셀프 1673 1465 1365 0
4 A0006039 서울 강남구 (주)동하힐탑셀프주유소 서울 강남구 논현로 640 20190105 SK에너지 셀프 1673 1465 1365 0
... ... ... ... ... ... ... ... ... ... ... ...
181709 A0032659 서울 중랑구 지에스칼텍스㈜ 소망주유소 서울 중랑구 망우로 475 20191227 GS칼텍스 셀프 0 1540 1389 1100
181710 A0032659 서울 중랑구 지에스칼텍스㈜ 소망주유소 서울 중랑구 망우로 475 20191228 GS칼텍스 셀프 0 1540 1389 1100
181711 A0032659 서울 중랑구 지에스칼텍스㈜ 소망주유소 서울 중랑구 망우로 475 20191229 GS칼텍스 셀프 0 1540 1389 1100
181712 A0032659 서울 중랑구 지에스칼텍스㈜ 소망주유소 서울 중랑구 망우로 475 20191230 GS칼텍스 셀프 0 1540 1389 1100
181713 A0032659 서울 중랑구 지에스칼텍스㈜ 소망주유소 서울 중랑구 망우로 475 20191231 GS칼텍스 셀프 0 1540 1389 1100
                       
181714 rows × 11 columns                  
 
 

2. Merge() - 병합

서로 다른 구성의 DataFrame이지만, 공통된 key값(컬럼)을 가지고 있다면 병합할 수 있습니다.

df1 = pd.DataFrame({
    '고객명': ['박세리', '이대호', '손흥민', '김연아', '마이클조던'],
    '생년월일': ['1980-01-02', '1982-02-22', '1993-06-12', '1988-10-16', '1970-03-03'],
    '성별': ['여자', '남자', '남자', '여자', '남자']})
df1
고객명	생년월일	성별
0	박세리	1980-01-02	여자
1	이대호	1982-02-22	남자
2	손흥민	1993-06-12	남자
3	김연아	1988-10-16	여자
4	마이클조던	1970-03-03	남자

 

 

df2 = pd.DataFrame({
    '고객명': ['김연아', '박세리', '손흥민', '이대호', '타이거우즈'],
    '연봉': ['2000원', '3000원', '1500원', '2500원', '3500원']})
df2
고객명	연봉
0	김연아	2000원
1	박세리	3000원
2	손흥민	1500원
3	이대호	2500원
4	타이거우즈	3500원

 

pd.merge(df1, df2)
	고객명	생년월일	성별	연봉
0	박세리	1980-01-02	여자	3000원
1	이대호	1982-02-22	남자	2500원
2	손흥민	1993-06-12	남자	1500원
3	김연아	1988-10-16	여자	2000원

 

 

1) 병합하는 방법 4가지

how 옵션 값을 지정하여 4가지 방식으로 병합을 할 수 있으며, 각기 다른 결과를 냅니다.

  • how : {left, right, outer, inner},
  • default로 설정된 값은inner 입니다.
# how='inner' 입니다.
pd.merge(df1, df2)
고객명	생년월일	성별	연봉
0	박세리	1980-01-02	여자	3000원
1	이대호	1982-02-22	남자	2500원
2	손흥민	1993-06-12	남자	1500원
3	김연아	1988-10-16	여자	2000원

pd.merge(df1, df2, how='left')
고객명	생년월일	성별	연봉
0	박세리	1980-01-02	여자	3000원
1	이대호	1982-02-22	남자	2500원
2	손흥민	1993-06-12	남자	1500원
3	김연아	1988-10-16	여자	2000원
4	마이클조던	1970-03-03	남자	NaN

pd.merge(df1, df2, how='right')
고객명	생년월일	성별	연봉
0	김연아	1988-10-16	여자	2000원
1	박세리	1980-01-02	여자	3000원
2	손흥민	1993-06-12	남자	1500원
3	이대호	1982-02-22	남자	2500원
4	타이거우즈	NaN	NaN	3500원

pd.merge(df1, df2, how='outer')
	고객명	생년월일	성별	연봉
0	박세리	1980-01-02	여자	3000원
1	이대호	1982-02-22	남자	2500원
2	손흥민	1993-06-12	남자	1500원
3	김연아	1988-10-16	여자	2000원
4	마이클조던	1970-03-03	남자	NaN
5	타이거우즈	NaN	NaN	3500원
 
 
2) 병합하려는 컬럼의 이름이 다른 경우
df1 = pd.DataFrame({
    '이름': ['박세리', '이대호', '손흥민', '김연아', '마이클조던'],
    '생년월일': ['1980-01-02', '1982-02-22', '1993-06-12', '1988-10-16', '1970-03-03'],
    '성별': ['여자', '남자', '남자', '여자', '남자']})
df1

df2 = pd.DataFrame({
    '고객명': ['김연아', '박세리', '손흥민', '이대호', '타이거우즈'],
    '연봉': ['2000원', '3000원', '1500원', '2500원', '3500원']})
df2

 

left_on과 right_on을 지정합니다.

이름과 고객명 컬럼이 모두 drop되지 않고 살아 있음을 확인합니다.

pd.merge(df1, df2, left_on='이름', right_on='고객명')
	이름	생년월일	성별	고객명	연봉
0	박세리	1980-01-02	여자	박세리	3000원
1	이대호	1982-02-22	남자	이대호	2500원
2	손흥민	1993-06-12	남자	손흥민	1500원
3	김연아	1988-10-16	여자	김연아	2000원

'pandas' 카테고리의 다른 글

matplotlib 그래프 종류  (0) 2023.12.15
matplotlib  (0) 2023.12.14
Groupby와 Pivot table  (0) 2023.12.12
데이터 전처리, 추가, 삭제, 변환  (0) 2023.12.12
복사와 결측치  (0) 2023.12.12

댓글