참조 :
한 권으로 끝내는 <판다스 노트>
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 |
댓글