2.4. 데이터프레임의 결합#
데이터를 이용하여 분석을 하는 경우 사용할 자료가 두 개 이상이 경우는 매우 흔한 일이다. 실제로 데이터 분석에서 하나의 자료만 가지고 수행하는 일은 매우 드물다. 이 절에서는 여러 개의 자료를 사용하는 경우 두 개의 자료를 서로 결합하여 새로운 자료를 만드는 것을 실습한다. 살펴 볼 내용은 다음과 같다.
데이터의 결합
식별자의 불일치
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
간단한 예제#
두 개의 데이터프레임 df1 과 df2 가 다음과 같이 주어졌다고 하자.
df1 = pd.DataFrame({
"name" : ["철수", "영이", "John"],
"age" : [23, 34, 19]
})
df1
| name | age | |
|---|---|---|
| 0 | 철수 | 23 |
| 1 | 영이 | 34 |
| 2 | John | 19 |
df2 = pd.DataFrame({
"name" : ["철수", "영이", "John"],
"sex" : ["M", "F", "M"]
})
df2
| name | sex | |
|---|---|---|
| 0 | 철수 | M |
| 1 | 영이 | F |
| 2 | John | M |
데이터프레임 df1 과 df2 에는 같은 이름을 가지는 열 name 이 있다. 우리는 두 개의 데이터프레임을 합쳐서 나이(age)와 성(sex) 이 모두 포함된 새로운 데이터프레임을 만들려고 한다.
이렇게 공통으로 포함된 열의 정보를 이용하여 두 개의 데이터프레임을 결합하려면 pandas 라이브러리의 merge() 함수 를 이용한다.
merge()함수의 첫 번째(왼쪽)와 두 번째 인자(오른쪽)에는 결합할 데이터프레임의 이름을 넣어준다.앞에
pd.를 붙여서pd.merge()로 사용하는 것은 함수merge()가 pandas 라이브러리에 있다는 것을 알려준다.선택문
on=에 두 데이터프레임에 결합의 기준이 되는 열이름을 문자열로 지정해준다. 결합의 기준으로 사용되는 열이름은 두 개의 데이터프레임에 모두 존재해야 한다.자료의 결합에 사용되는 공통으로 포함된 열의 내용을 식별자(key, identifier,..) 라고 부른다. 이 예제에서 식별자는 사람의 이름이다.
다음 코드의 결과를 먼저 보자.
pd.merge(df1, df2, on="name")
| name | age | sex | |
|---|---|---|---|
| 0 | 철수 | 23 | M |
| 1 | 영이 | 34 | F |
| 2 | John | 19 | M |
두 개의 데이터프레임이 지정된 열 name 에 의하여 결합되어 나이(age)와 성(sex)이 같이 나타나게 된다.
식별자의 불일치#
만약 두 개의 데이터프레임에 있는 식별자에 포함된 자료가 다르면 어떻게 될까?
다음과 같이 John 의 자료가 빠져 있는 데이터프레임 df3을 df1 과 결합해 보자.
df3 = pd.DataFrame({
"name" : ["철수", "영이"],
"weight" : [55, 44]
})
df3
| name | weight | |
|---|---|---|
| 0 | 철수 | 55 |
| 1 | 영이 | 44 |
pd.merge(df1, df3, on="name")
| name | age | weight | |
|---|---|---|---|
| 0 | 철수 | 23 | 55 |
| 1 | 영이 | 34 | 44 |
위의 결과에서 John 의 자료가 사라져 버렸다. 물론 몸무게 값이 없는 John 의 자료가 필요없을 수도 있지만 많은 경우 자료를 유지해야 한다.
이렇게 식별자의 항목이 다른 경우, 결합의 기준이 되는 식별자를 데이터프레임의 위치로 지정할 수 있다. 위에서 함수 merge()를 설명할 때 사용되는 데이터프레임의 위치에 따라서 왼쪽 (첫 번째 인자) 과 오른쪽 (두 번째 인자)으로 나타냈다.
pd.merge(left_df, right_df, on="name", how="inner")
how='left': 식별자는 왼쪽 데이터프레임에만 있는 것으로 선택how='right': 식별자는 오른쪽 데이터프레임에만 있는 것으로 선택how='inner': 식별자는 두 데이터프레임에 공통인 것으로 선택how='outer': 식별자는 두 데이터프레임에 나타난 모든 것으로 선택
식별자를 선택하는 선택명령문 how= 을 지정하지 않으면 자동으로 how='inner' 이 지정된다.

이제 결합시 기준이 되는 식별자가 왼쪽에 있는 데이터프레임 df1 에 있다는 것을 선택명령문 how='left' 로 알려주자.
pd.merge(df1, df3, on="name", how='left')
| name | age | weight | |
|---|---|---|---|
| 0 | 철수 | 23 | 55.0 |
| 1 | 영이 | 34 | 44.0 |
| 2 | John | 19 | NaN |
이제 John 의 자료가 나타나고 John 의 키는 결측값(NaN) 으로 표시된다.
만약 두 개의 식별자에 서로 다른 내용이 나타나면 어떻게 될까?
이제 새로운 사람 흥민의 자료를 가진 데이터프레임 df4를 df1 과 결합하는 예를 살펴보자. 아래 코드에서 선택명령문 how= 에 지정된 문자열에 따라서 결합의 결과가 어떻게 다른지 보자.
df4 = pd.DataFrame({
"name" : ["철수", "영이", "흥민"],
"height" : [167, 175, 183]
})
df4
| name | height | |
|---|---|---|
| 0 | 철수 | 167 |
| 1 | 영이 | 175 |
| 2 | 흥민 | 183 |
위에서 본 바와 같이 선택명령문 how='left'이 결합시 기준이 데이터프레임 df1 에 있다는 것을 알려준다.
pd.merge(df1, df4, on="name", how='left')
| name | age | height | |
|---|---|---|---|
| 0 | 철수 | 23 | 167.0 |
| 1 | 영이 | 34 | 175.0 |
| 2 | John | 19 | NaN |
선택명령문 how='right'이 결합시 기준이 데이터프레임 df4 에 있다는 것을 알려준다.
pd.merge(df1, df4, on="name", how='right')
| name | age | height | |
|---|---|---|---|
| 0 | 철수 | 23.0 | 167 |
| 1 | 영이 | 34.0 | 175 |
| 2 | 흥민 | NaN | 183 |
선택명령문 how='inner'이 결합시 기준이 데이터프레임 df1& df4 에서 공통된 것임을 알려준다.
pd.merge(df1, df4, on="name", how='inner')
| name | age | height | |
|---|---|---|---|
| 0 | 철수 | 23 | 167 |
| 1 | 영이 | 34 | 175 |
선택명령문 how='outer'이 결합시 기준이 데이터프레임 df1& df4의 모든 것임을 알려준다.
pd.merge(df1, df4, on="name", how='outer')
| name | age | height | |
|---|---|---|---|
| 0 | 철수 | 23.0 | 167.0 |
| 1 | 영이 | 34.0 | 175.0 |
| 2 | John | 19.0 | NaN |
| 3 | 흥민 | NaN | 183.0 |
전체 사업장 데이터와 음식 사업장 데이터의 결합#
이번에는 전체 사업장 데이터 (전체_사업장.csv)와 음식 사업장 데이터 (음식_사업장.csv) 을 결합하는 작업을 해보려고 한다.
전체 사업장 데이터에는 2010년부터 2021년까지 11년간의 7개 특별광역시(서울, 인천, 대전, 광주, 대구, 울산, 부산) 정보가 있다.
total = pd.read_csv("https://uos-bigdata.github.io/lab_data/docs/assets/data_lab_bokji/dat_total.csv", encoding = 'UTF8')
total
| 연도 | 시도 | 산재_평균근로자수 | 산재만_가입된사업장수 | 산재_가입된사업장수 | 고용_평균근로자수 | 고용만_가입된사업장수 | 고용_가입된사업장수 | |
|---|---|---|---|---|---|---|---|---|
| 0 | 2010.0 | 광주 | 6.863187 | 52 | 1820 | 6.847419 | 1 | 1763 |
| 1 | 2010.0 | 대구 | 7.366627 | 82 | 2523 | 7.051240 | 7 | 2420 |
| 2 | 2010.0 | 대전 | 9.100746 | 59 | 1340 | 8.816680 | 3 | 1271 |
| 3 | 2010.0 | 부산 | 8.126126 | 121 | 3108 | 7.622692 | 11 | 2979 |
| 4 | 2010.0 | 서울 | 10.971553 | 343 | 11741 | 10.869985 | 30 | 11391 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 79 | 2021.0 | 대전 | 2.658709 | 434 | 7917 | 1.887973 | 369 | 8007 |
| 80 | 2021.0 | 부산 | 2.874647 | 688 | 17367 | 1.909389 | 660 | 17680 |
| 81 | 2021.0 | 서울 | 7.487265 | 2375 | 59009 | 2.020801 | 1410 | 58700 |
| 82 | 2021.0 | 울산 | 3.442591 | 273 | 5095 | 2.080108 | 262 | 5193 |
| 83 | 2021.0 | 인천 | 2.604997 | 703 | 15648 | 1.916362 | 444 | 15615 |
84 rows × 8 columns
음식 사업장 데이터에는 2017년부터 2021년까지 5년간의 7개 특별광역시(서울, 인천, 대전, 광주, 대구, 울산, 부산) 정보가 있다.
food = pd.read_csv("https://uos-bigdata.github.io/lab_data/docs/assets/data_lab_bokji/data_food.csv", encoding = 'UTF8')
food
| 시도 | 연도 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|---|
| 0 | 광주 | 2017.0 | 796 | 801 |
| 1 | 광주 | 2018.0 | 1121 | 1136 |
| 2 | 광주 | 2019.0 | 1674 | 1679 |
| 3 | 광주 | 2020.0 | 1757 | 1763 |
| 4 | 광주 | 2021.0 | 1727 | 1734 |
| 5 | 대구 | 2017.0 | 1367 | 1375 |
| 6 | 대구 | 2018.0 | 1739 | 1749 |
| 7 | 대구 | 2019.0 | 2523 | 2531 |
| 8 | 대구 | 2020.0 | 2428 | 2434 |
| 9 | 대구 | 2021.0 | 2619 | 2624 |
| 10 | 대전 | 2017.0 | 933 | 927 |
| 11 | 대전 | 2018.0 | 1093 | 1131 |
| 12 | 대전 | 2019.0 | 1588 | 1606 |
| 13 | 대전 | 2020.0 | 1767 | 1781 |
| 14 | 대전 | 2021.0 | 1634 | 1652 |
| 15 | 부산 | 2017.0 | 1713 | 1720 |
| 16 | 부산 | 2018.0 | 2159 | 2168 |
| 17 | 부산 | 2019.0 | 3205 | 3215 |
| 18 | 부산 | 2020.0 | 3508 | 3508 |
| 19 | 부산 | 2021.0 | 3829 | 3836 |
| 20 | 서울 | 2017.0 | 6069 | 6117 |
| 21 | 서울 | 2018.0 | 7967 | 8000 |
| 22 | 서울 | 2019.0 | 10576 | 10596 |
| 23 | 서울 | 2020.0 | 10612 | 10631 |
| 24 | 서울 | 2021.0 | 10752 | 10796 |
| 25 | 울산 | 2017.0 | 541 | 541 |
| 26 | 울산 | 2018.0 | 651 | 654 |
| 27 | 울산 | 2019.0 | 996 | 998 |
| 28 | 울산 | 2020.0 | 1137 | 1138 |
| 29 | 울산 | 2021.0 | 1046 | 1048 |
| 30 | 인천 | 2017.0 | 1319 | 1318 |
| 31 | 인천 | 2018.0 | 1817 | 1835 |
| 32 | 인천 | 2019.0 | 2718 | 2731 |
| 33 | 인천 | 2020.0 | 2886 | 2892 |
| 34 | 인천 | 2021.0 | 2891 | 2898 |
연도,시도로 데이터를 결합해줄 것이기 때문에 먼저 사업장 데이터처럼 음식 사업장 데이터를 연도 기준으로 정렬해준다.
food = food.sort_values(by ="연도")
food
| 시도 | 연도 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|---|
| 0 | 광주 | 2017.0 | 796 | 801 |
| 20 | 서울 | 2017.0 | 6069 | 6117 |
| 30 | 인천 | 2017.0 | 1319 | 1318 |
| 5 | 대구 | 2017.0 | 1367 | 1375 |
| 10 | 대전 | 2017.0 | 933 | 927 |
| 25 | 울산 | 2017.0 | 541 | 541 |
| 15 | 부산 | 2017.0 | 1713 | 1720 |
| 21 | 서울 | 2018.0 | 7967 | 8000 |
| 11 | 대전 | 2018.0 | 1093 | 1131 |
| 26 | 울산 | 2018.0 | 651 | 654 |
| 6 | 대구 | 2018.0 | 1739 | 1749 |
| 31 | 인천 | 2018.0 | 1817 | 1835 |
| 1 | 광주 | 2018.0 | 1121 | 1136 |
| 16 | 부산 | 2018.0 | 2159 | 2168 |
| 22 | 서울 | 2019.0 | 10576 | 10596 |
| 32 | 인천 | 2019.0 | 2718 | 2731 |
| 27 | 울산 | 2019.0 | 996 | 998 |
| 17 | 부산 | 2019.0 | 3205 | 3215 |
| 2 | 광주 | 2019.0 | 1674 | 1679 |
| 12 | 대전 | 2019.0 | 1588 | 1606 |
| 7 | 대구 | 2019.0 | 2523 | 2531 |
| 18 | 부산 | 2020.0 | 3508 | 3508 |
| 3 | 광주 | 2020.0 | 1757 | 1763 |
| 28 | 울산 | 2020.0 | 1137 | 1138 |
| 33 | 인천 | 2020.0 | 2886 | 2892 |
| 8 | 대구 | 2020.0 | 2428 | 2434 |
| 23 | 서울 | 2020.0 | 10612 | 10631 |
| 13 | 대전 | 2020.0 | 1767 | 1781 |
| 24 | 서울 | 2021.0 | 10752 | 10796 |
| 29 | 울산 | 2021.0 | 1046 | 1048 |
| 4 | 광주 | 2021.0 | 1727 | 1734 |
| 14 | 대전 | 2021.0 | 1634 | 1652 |
| 19 | 부산 | 2021.0 | 3829 | 3836 |
| 9 | 대구 | 2021.0 | 2619 | 2624 |
| 34 | 인천 | 2021.0 | 2891 | 2898 |
두 데이터를 결합하기에 앞서 전체 사업장 데이터(total)와 음식 사업장 데이터(food)를 가공해 줄 것이다.
total에서는 결합에 필요한연도,시도,산재만_가입된사업장수,고용_가입된사업장수열을 추출하고2015년~2018년4년도의 데이터를 저장한다.시도열 중에서도 서울, 부산, 인천의 데이터만 사용할 것이다.food에서는2017~2019년3년도의 데이터를 추출할 것이다.시도열 중에서도 서울, 부산, 인천의 데이터만 사용할 것이다.
total.columns =["연도","시도","산재_평균근로자수","산재만_가입된사업장수","산재_가입된사업장수","고용_평균근로자수", "고용만_가입된사업장수","고용_가입된사업장수"]
total_sub = total.loc[:,["연도", "시도","산재_가입된사업장수", "고용_가입된사업장수"]]
total_sub
| 연도 | 시도 | 산재_가입된사업장수 | 고용_가입된사업장수 | |
|---|---|---|---|---|
| 0 | 2010.0 | 광주 | 1820 | 1763 |
| 1 | 2010.0 | 대구 | 2523 | 2420 |
| 2 | 2010.0 | 대전 | 1340 | 1271 |
| 3 | 2010.0 | 부산 | 3108 | 2979 |
| 4 | 2010.0 | 서울 | 11741 | 11391 |
| ... | ... | ... | ... | ... |
| 79 | 2021.0 | 대전 | 7917 | 8007 |
| 80 | 2021.0 | 부산 | 17367 | 17680 |
| 81 | 2021.0 | 서울 | 59009 | 58700 |
| 82 | 2021.0 | 울산 | 5095 | 5193 |
| 83 | 2021.0 | 인천 | 15648 | 15615 |
84 rows × 4 columns
total_sub = total_sub.loc[(total_sub["연도"]>=2015)&(total_sub["연도"]<=2018)]
total_sub= total_sub.loc[(total_sub["시도"]=="서울")|(total_sub["시도"]=="부산")|(total_sub["시도"]=="인천")]
total_sub = total_sub.reset_index(drop=True)
total_sub
| 연도 | 시도 | 산재_가입된사업장수 | 고용_가입된사업장수 | |
|---|---|---|---|---|
| 0 | 2015.0 | 부산 | 7423 | 7289 |
| 1 | 2015.0 | 서울 | 26025 | 25641 |
| 2 | 2015.0 | 인천 | 5850 | 5702 |
| 3 | 2016.0 | 부산 | 8507 | 8275 |
| 4 | 2016.0 | 서울 | 30761 | 30038 |
| 5 | 2016.0 | 인천 | 6755 | 6602 |
| 6 | 2017.0 | 부산 | 9748 | 9543 |
| 7 | 2017.0 | 서울 | 34718 | 34114 |
| 8 | 2017.0 | 인천 | 8013 | 7800 |
| 9 | 2018.0 | 부산 | 12433 | 11640 |
| 10 | 2018.0 | 서울 | 45766 | 43654 |
| 11 | 2018.0 | 인천 | 11109 | 10323 |
food_sub = food.loc[(food["연도"]>=2017)&(food["연도"]<=2019)]
food_sub = food.loc[(food["시도"]=="서울")|(food["시도"]=="부산")|(food["시도"]=="인천")]
food_sub = food_sub.reset_index(drop=True)
food_sub
| 시도 | 연도 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|---|
| 0 | 서울 | 2017.0 | 6069 | 6117 |
| 1 | 인천 | 2017.0 | 1319 | 1318 |
| 2 | 부산 | 2017.0 | 1713 | 1720 |
| 3 | 서울 | 2018.0 | 7967 | 8000 |
| 4 | 인천 | 2018.0 | 1817 | 1835 |
| 5 | 부산 | 2018.0 | 2159 | 2168 |
| 6 | 서울 | 2019.0 | 10576 | 10596 |
| 7 | 인천 | 2019.0 | 2718 | 2731 |
| 8 | 부산 | 2019.0 | 3205 | 3215 |
| 9 | 부산 | 2020.0 | 3508 | 3508 |
| 10 | 인천 | 2020.0 | 2886 | 2892 |
| 11 | 서울 | 2020.0 | 10612 | 10631 |
| 12 | 서울 | 2021.0 | 10752 | 10796 |
| 13 | 부산 | 2021.0 | 3829 | 3836 |
| 14 | 인천 | 2021.0 | 2891 | 2898 |
데이터프레임 total_sub 과 food_sub 에는 같은 이름을 가지는 열 연도 와 시도가 있다. 우리는 두 개의 데이터프레임을 전체 사업장과 음식 사업장 모두를 한 번에 볼 수 있는 새로운 데이터프레임을 만들 것이다.
아래의 결과를 보면 두 개의 데이터프레임이 지정된 열 연도와 시도 에 의하여 결합되어 나타나게 된다.
결과에서 2015년,2016년,2019년 의 자료가 사라져 버린 것을 확인할 수 있다.
how='를 따로 설정해주지 않았기 때문에 기본값인how='inner'로 결과가 나타난다. 물론 2015년,2016년,2019년 자료가 필요없을 수도 있지만 많은 경우 자료를 유지해야 한다.
pd.merge(total_sub, food_sub, on=["연도","시도"])
| 연도 | 시도 | 산재_가입된사업장수 | 고용_가입된사업장수 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|---|---|---|
| 0 | 2017.0 | 부산 | 9748 | 9543 | 1713 | 1720 |
| 1 | 2017.0 | 서울 | 34718 | 34114 | 6069 | 6117 |
| 2 | 2017.0 | 인천 | 8013 | 7800 | 1319 | 1318 |
| 3 | 2018.0 | 부산 | 12433 | 11640 | 2159 | 2168 |
| 4 | 2018.0 | 서울 | 45766 | 43654 | 7967 | 8000 |
| 5 | 2018.0 | 인천 | 11109 | 10323 | 1817 | 1835 |
pd.merge(total_sub, food_sub, on=["연도","시도"], how="inner")
| 연도 | 시도 | 산재_가입된사업장수 | 고용_가입된사업장수 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|---|---|---|
| 0 | 2017.0 | 부산 | 9748 | 9543 | 1713 | 1720 |
| 1 | 2017.0 | 서울 | 34718 | 34114 | 6069 | 6117 |
| 2 | 2017.0 | 인천 | 8013 | 7800 | 1319 | 1318 |
| 3 | 2018.0 | 부산 | 12433 | 11640 | 2159 | 2168 |
| 4 | 2018.0 | 서울 | 45766 | 43654 | 7967 | 8000 |
| 5 | 2018.0 | 인천 | 11109 | 10323 | 1817 | 1835 |
이제 how 옵션을 바꾸어 결합 시 기준이 되는 식별자에 조건을 바꾸어보자.
먼저 결합시 기준이 되는 식별자가 왼쪽에 있는 데이터프레임 total_sub 에 있다는 것을 선택명령문 how='left' 로 알려주자.
아래의 결과를 확인해보면 2015년도 의 자료가 나타나지만 산재_음식사업장수과 고용_음식사업장수에서 결측값(NaN) 으로 표시된다.
pd.merge(total_sub, food_sub, on=["연도","시도"], how='left')
| 연도 | 시도 | 산재_가입된사업장수 | 고용_가입된사업장수 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|---|---|---|
| 0 | 2015.0 | 부산 | 7423 | 7289 | NaN | NaN |
| 1 | 2015.0 | 서울 | 26025 | 25641 | NaN | NaN |
| 2 | 2015.0 | 인천 | 5850 | 5702 | NaN | NaN |
| 3 | 2016.0 | 부산 | 8507 | 8275 | NaN | NaN |
| 4 | 2016.0 | 서울 | 30761 | 30038 | NaN | NaN |
| 5 | 2016.0 | 인천 | 6755 | 6602 | NaN | NaN |
| 6 | 2017.0 | 부산 | 9748 | 9543 | 1713.0 | 1720.0 |
| 7 | 2017.0 | 서울 | 34718 | 34114 | 6069.0 | 6117.0 |
| 8 | 2017.0 | 인천 | 8013 | 7800 | 1319.0 | 1318.0 |
| 9 | 2018.0 | 부산 | 12433 | 11640 | 2159.0 | 2168.0 |
| 10 | 2018.0 | 서울 | 45766 | 43654 | 7967.0 | 8000.0 |
| 11 | 2018.0 | 인천 | 11109 | 10323 | 1817.0 | 1835.0 |
다음 결합시 기준이 되는 식별자가 오른쪽에 있는 데이터프레임 total_sub 에 있다는 것을 선택명령문 how='right' 로 알려주자.
2019년도 의 자료가 나타나지만 산재_가입된사업장수과 고용_가입된사업장수에서 결측값(NaN) 으로 표시되는 것을 확인할 수 있다.
pd.merge(total_sub, food_sub, on=["연도","시도"], how='right')
| 연도 | 시도 | 산재_가입된사업장수 | 고용_가입된사업장수 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|---|---|---|
| 0 | 2017.0 | 서울 | 34718.0 | 34114.0 | 6069 | 6117 |
| 1 | 2017.0 | 인천 | 8013.0 | 7800.0 | 1319 | 1318 |
| 2 | 2017.0 | 부산 | 9748.0 | 9543.0 | 1713 | 1720 |
| 3 | 2018.0 | 서울 | 45766.0 | 43654.0 | 7967 | 8000 |
| 4 | 2018.0 | 인천 | 11109.0 | 10323.0 | 1817 | 1835 |
| 5 | 2018.0 | 부산 | 12433.0 | 11640.0 | 2159 | 2168 |
| 6 | 2019.0 | 서울 | NaN | NaN | 10576 | 10596 |
| 7 | 2019.0 | 인천 | NaN | NaN | 2718 | 2731 |
| 8 | 2019.0 | 부산 | NaN | NaN | 3205 | 3215 |
| 9 | 2020.0 | 부산 | NaN | NaN | 3508 | 3508 |
| 10 | 2020.0 | 인천 | NaN | NaN | 2886 | 2892 |
| 11 | 2020.0 | 서울 | NaN | NaN | 10612 | 10631 |
| 12 | 2021.0 | 서울 | NaN | NaN | 10752 | 10796 |
| 13 | 2021.0 | 부산 | NaN | NaN | 3829 | 3836 |
| 14 | 2021.0 | 인천 | NaN | NaN | 2891 | 2898 |
다음 결합시 기준이 되는 식별자가 오른쪽에 있는 데이터프레임 total_sub 에 있다는 것을 선택명령문 how='outer' 로 알려주자.
이제2015년도 2019년도 의 자료가 나타나지만 ‘ 산재_음식사업장수과 고용_음식사업장수에서 2015년도 자료가 결측값(NaN) 으로 표시되고 산재_가입된사업장수과 고용_가입된사업장수에서 2019년도 지료가 결측값(NaN) 으로 표시되는 것을 확인할 수 있다.
pd.merge(total_sub, food_sub, on=["연도","시도"], how='outer')
| 연도 | 시도 | 산재_가입된사업장수 | 고용_가입된사업장수 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|---|---|---|
| 0 | 2015.0 | 부산 | 7423.0 | 7289.0 | NaN | NaN |
| 1 | 2015.0 | 서울 | 26025.0 | 25641.0 | NaN | NaN |
| 2 | 2015.0 | 인천 | 5850.0 | 5702.0 | NaN | NaN |
| 3 | 2016.0 | 부산 | 8507.0 | 8275.0 | NaN | NaN |
| 4 | 2016.0 | 서울 | 30761.0 | 30038.0 | NaN | NaN |
| 5 | 2016.0 | 인천 | 6755.0 | 6602.0 | NaN | NaN |
| 6 | 2017.0 | 부산 | 9748.0 | 9543.0 | 1713.0 | 1720.0 |
| 7 | 2017.0 | 서울 | 34718.0 | 34114.0 | 6069.0 | 6117.0 |
| 8 | 2017.0 | 인천 | 8013.0 | 7800.0 | 1319.0 | 1318.0 |
| 9 | 2018.0 | 부산 | 12433.0 | 11640.0 | 2159.0 | 2168.0 |
| 10 | 2018.0 | 서울 | 45766.0 | 43654.0 | 7967.0 | 8000.0 |
| 11 | 2018.0 | 인천 | 11109.0 | 10323.0 | 1817.0 | 1835.0 |
| 12 | 2019.0 | 서울 | NaN | NaN | 10576.0 | 10596.0 |
| 13 | 2019.0 | 인천 | NaN | NaN | 2718.0 | 2731.0 |
| 14 | 2019.0 | 부산 | NaN | NaN | 3205.0 | 3215.0 |
| 15 | 2020.0 | 부산 | NaN | NaN | 3508.0 | 3508.0 |
| 16 | 2020.0 | 인천 | NaN | NaN | 2886.0 | 2892.0 |
| 17 | 2020.0 | 서울 | NaN | NaN | 10612.0 | 10631.0 |
| 18 | 2021.0 | 서울 | NaN | NaN | 10752.0 | 10796.0 |
| 19 | 2021.0 | 부산 | NaN | NaN | 3829.0 | 3836.0 |
| 20 | 2021.0 | 인천 | NaN | NaN | 2891.0 | 2898.0 |
요약#
두 개의 데이터프레임을 결합하는 경우 pandas 라이브러리의 함수 merge() 를 사용하며 식별자가 포함된 공통의 열은 on= 으로 지정한다. 결합의 방향을 how=로 지정한다.