Pythonライブラリ講座

concat,merge,joinの違いは?DataFrameの結合を徹底解説!

前のページ|次のページ

13章ではPandasのDataFrameの結合方法である『内部結合・外部結合・左結合・右結合』について解説します。

また、DataFrameの結合に使う『pd.concat()関数』『pd.merge()関数』『joinメソッド』について解説します。

本記事を読めばDataFrameの結合について体系的に理解することができます。

ぜひ最後まで読んでいってください!

本連載講座【Python ライブラリ編】では、データサイエンスに必要なPythonライブラリやその使い方を基礎から学ぶことができます。

NumPyPandasMatplotlibScipySeabornについて、初学者の方にも分かりやすいよう丁寧に解説しています。

さらに、学習した内容を定着させられるように各章演習問題を用意しています。

・Pythonでデータ分析ができるようになりたい

・Pythonの基礎事項は一通り学んだので、さらに深く学びたい

このように考えている方はTech Teacherが運営する【Python ライブラリ編】で、Pythonによるデータサイエンスの学習をすることをお勧めします!

なお、『Pythonについて全く知らない』・『Pythonの基礎事項がまだ分かっていない』という方は、まずコチラの【Python 基礎編】で基礎を一通り学習してからライブラリ編に取り掛かりましょう!

<ライブラリ編 目次>

<ライブラリの基礎>
1章:ライブラリとは

<NumPy>
2章:NumPyの概要と配列(ndarray)
3章:統計量や次元の取得/ソート
4章:配列のインデックス
5章:numpy.whereによる条件制御
6章:配列の結合/分割
7章:乱数

<SciPy>
8章:SciPyの概要と基本操作

<Pandas>
9章:SeriesDataFrame/統計量の取得
10章:データの読み込み/書き込み
11章:データの取り出し/追加
12章:データのソート
13章:データの結合
14章:階層型インデックス
15章:groupbyによる集計
16章:マッピング処理
17章:欠損値の扱い

<Matplotlib>
18章:Matplotlibの概要
19章:pyplotインターフェース
20章:オブジェクト指向インターフェース

<Seaborn>
21章:Seabornの概要と基本操作

データのさまざまな結合方法

データの結合とは・キーとは

2つ以上の表形式のデータを基に1つの表を生成することを『結合』と言います。

また、結合における『キー』とは、結合の軸となる列のことです。

例えばキーを『name』列として2つの表を内部結合すると以下の図のようになります。

なお、内部結合とは元データに共通するデータのみを取り出して結合する結合方法です。後程詳しく説明します。

内部結合 DataFrame

データの結合にはいくつかの方法があり、それぞれを状況に応じて使い分ける必要があります。

まずはそれぞれの結合方法について図とともに理解していきましょう。

内部結合

内部結合』は元データの両方に共通のキーの値があるときに結合します。

内部結合 ベン図

先ほどの例ではキーを「name」列として内部結合を行いました。

内部結合 DataFrame

このとき、両方の「name」列に存在する「Alice, Bob, Charlie, Emma」の4つのデータのみが取り出されていることが分かると思います。

外部結合(全結合)

外部結合』は元データの少なくとも一方にキーの値があるときに結合します。

外部結合 ベン図

先ほどの例で外部結合を行った場合、以下のような結果になります。

外部結合 DataFrame

いずれかの「name」列に存在する、「Alice, Bob, Charlie, Emma, Grace, Hana, David, Frank」の8つのデータが取り出されていることが分かると思います。

なお、値が存在しない要素はNaNで置き換えられます。

また、「age」列がfloat型になってしまっているのはNaNの影響です。

左結合

左結合』は左側のデータにあるキーの値をもとに結合します。

ここで、今回紹介するデータの結合における『』は引数として先に指定されたデータを表すこととします。

左結合 ベン図

先ほどの例で左結合を行うと以下のような結果が得られます。

左結合 DataFrame

上の図において「左のデータ」は結合前の上側のデータを指します。

左のデータの「name」列にある「Alice, Bob, Charlie, Emma, Grace, Hana」の6つのデータが取り出されていることが分かります。

右結合

右結合』は右側のデータにあるキーの値をもとに結合します。

ここで、今回紹介するデータの結合における『』は引数として後に指定されたデータを表すこととします。

右結合 ベン図

先ほどの例で右結合を行うと以下のような結果が得られます。

右結合 DataFrame

上の図において「右のデータ」は結合前の下側のデータを指します。

右のデータの「name」列にある「Alice, Bob, Charlie, David, Emma, Frank」の6つのデータが取り出されていることが分かります。

データの準備

以下のコードを実行して、今回使用する2つのDataFrame「df1」、「df2」を定義しておきましょう。

data1 = {
    'ID':[100,101,102,104,106,107],
    'name':['Alice', 'Bob', 'Charlie', 'Emma', 'Grace', 'Hana'],
    'city':['New York', 'Los Angeles', 'New York', 'Houston', 'Los Angeles','Chicago']
}

data2 = {
    'ID':[100,101,102,103,104,105],
    'name':['Alice', 'Bob', 'Charlie', 'David', 'Emma','Frank'],
    'age':[24,35,22,56,47,38]
}

df1 = pd.DataFrame(data1).set_index('ID')
df2 = pd.DataFrame(data2).set_index('ID')

作成したdf1、df2の内容はそれぞれ以下の画像の通りです。

DataFrame1
DataFrame2

concat()関数による縦横の連結

pd.concat()』関数を用いると、2つのDataFrameを縦方向・横方向に連結することができます。

こちらの関数はデフォルトで外部結合が行われます。

pd.concat(結合するDataFrameのリスト)

本記事では基本的な使い方と引数『axis』『join』について解説します。

引数axis:縦結合・横結合

引数『axis』により、縦方向・横方向の連結のいずれかを選択できます。

・axis=0 → 縦方向の連結(デフォルト)
・axis=1 → 横方向の連結

まずは縦結合の例を示します。

#縦方向の連結
pd.concat([df1, df2])

#df1:
#        name         city
#ID                       
#100    Alice     New York
#101      Bob  Los Angeles
#102  Charlie     New York
#104     Emma      Houston
#106    Grace  Los Angeles
#107     Hana      Chicago

#df2:
#        name  age
#ID               
#100    Alice   24
#101      Bob   35
#102  Charlie   22
#103    David   56
#104     Emma   47
#105    Frank   38
DataFrame3

2つのDataFrameがそのまま縦に連結されているのが分かると思います。

外部結合においてデータが存在しない要素はNaNで置き換えられます。

次にaxis=1として横結合の例を示します。

#横方向の連結
pd.concat([df1, df2], axis=1)

#df1:
#        name         city
#ID                       
#100    Alice     New York
#101      Bob  Los Angeles
#102  Charlie     New York
#104     Emma      Houston
#106    Grace  Los Angeles
#107     Hana      Chicago

#df2:
#        name  age
#ID               
#100    Alice   24
#101      Bob   35
#102  Charlie   22
#103    David   56
#104     Emma   47
#105    Frank   38
DataFrame4

横結合においても、データが存在しない要素はNaNに置き換えられます。

引数join:内部結合・外部結合

引数『join』により、内部結合と外部結合を選択することができます。

・join=’inner’ → 2つのデータに共通する列名のみを結合
・join=’outer’ → 2つのデータに現れるすべての列名に対して結合(デフォルト)

まずは内部結合の例を見てみましょう。

#内部結合
pd.concat([df1, df2], join='inner')

#df1:
#        name         city
#ID                       
#100    Alice     New York
#101      Bob  Los Angeles
#102  Charlie     New York
#104     Emma      Houston
#106    Grace  Los Angeles
#107     Hana      Chicago

#df2:
#        name  age
#ID               
#100    Alice   24
#101      Bob   35
#102  Charlie   22
#103    David   56
#104     Emma   47
#105    Frank   38
DataFrame5

2つのデータに共通する列は「name」なので、この列のみが縦結合されています。

続いて外部結合です。デフォルトでjoin=’outer’になっているので、join引数を指定しない場合と同様の結果が得られます。

#外部結合
pd.concat([df1, df2], join='outer')

#df1:
#        name         city
#ID                       
#100    Alice     New York
#101      Bob  Los Angeles
#102  Charlie     New York
#104     Emma      Houston
#106    Grace  Los Angeles
#107     Hana      Chicago

#df2:
#        name  age
#ID               
#100    Alice   24
#101      Bob   35
#102  Charlie   22
#103    David   56
#104     Emma   47
#105    Frank   38
DataFrame6

2つのデータの少なくとも一方に登場する列すべてに対して縦結合が行われます。

merge()関数による列をキーとした結合

pd.merge()』関数を用いると、キーと結合方法を指定して2つのDataFrameを結合することができます。

こちらの関数はデフォルトで内部結合が行われます。

pd.merge(DataFrame1, DataFrame2)

のように書いたとき、第一引数の「DataFrame1」が、第二引数の「DataFrame2」がのデータとなります。

引数on:キーとなる列を指定

引数『on』により、キーとなる列を指定することができます。

on=列名」とすることで指定した列名を軸に種々の結合が行われます。

省略すると自動でキーが設定されますが、プログラムを読みやすくするためにもキーを明示しておくと良いでしょう。

以下の例では、キーを「name」列としてdf1とdf2を結合しています。

#内部結合
pd.merge(df1, df2, on='name')
DataFrame7

なお、デフォルトで内部結合が行われているので、両方のデータに登場する「Alice, Bob, Charlie, Emma」のデータのみが取り出されています。

pd.merge()関数で結合を行うと、結合後のインデックスは0から始まる連番になります。

引数how:結合方法を指定

引数『how』により、結合方法を指定することができます。

・how=’inner’ → 内部結合(デフォルト)
・how=’outer’ → 外部結合
・how=’left’ → 左結合
・how=’right’ → 右結合

キーを「name」列として、それぞれの結合方法の違いを確認してみましょう。

記事の冒頭で紹介した各結合方法の説明を参照しながら、結果を見比べてみてください。

#内部結合
pd.merge(df1, df2, on='name', how='inner')

#df1:
#        name         city
#ID                       
#100    Alice     New York
#101      Bob  Los Angeles
#102  Charlie     New York
#104     Emma      Houston
#106    Grace  Los Angeles
#107     Hana      Chicago

#df2:
#        name  age
#ID               
#100    Alice   24
#101      Bob   35
#102  Charlie   22
#103    David   56
#104     Emma   47
#105    Frank   38
DataFrame7
#外部結合
pd.merge(df1, df2, on='name', how='outer')

#df1:
#        name         city
#ID                       
#100    Alice     New York
#101      Bob  Los Angeles
#102  Charlie     New York
#104     Emma      Houston
#106    Grace  Los Angeles
#107     Hana      Chicago

#df2:
#        name  age
#ID               
#100    Alice   24
#101      Bob   35
#102  Charlie   22
#103    David   56
#104     Emma   47
#105    Frank   38
DataFrame8
#左結合
pd.merge(df1, df2, on='name', how='left')

#df1:
#        name         city
#ID                       
#100    Alice     New York
#101      Bob  Los Angeles
#102  Charlie     New York
#104     Emma      Houston
#106    Grace  Los Angeles
#107     Hana      Chicago

#df2:
#        name  age
#ID               
#100    Alice   24
#101      Bob   35
#102  Charlie   22
#103    David   56
#104     Emma   47
#105    Frank   38
DataFrame9
#右結合
pd.merge(df1, df2, on='name', how='right')

#df1:
#        name         city
#ID                       
#100    Alice     New York
#101      Bob  Los Angeles
#102  Charlie     New York
#104     Emma      Houston
#106    Grace  Los Angeles
#107     Hana      Chicago

#df2:
#        name  age
#ID               
#100    Alice   24
#101      Bob   35
#102  Charlie   22
#103    David   56
#104     Emma   47
#105    Frank   38
DataFrame10

joinメソッドによるインデックスをキーとした結合

join』メソッドを用いるとインデックスをキーとして2つのDataFrameを結合することができます。

こちらのメソッドは左結合がデフォルトになっています。

すなわち、左のデータのインデックスに合わせて結合されます。

左のDataFrame.join(右のDataFrame)

とすることで、呼び出し元DataFrameのインデックスをキーとして結合します。

なお、「pd.join()」関数は存在しないので注意しましょう。

引数how:結合方法を指定

引数『how』により、結合方法を指定することができます。

指定の仕方はmerge()関数と同様です。

・how=’inner’ → 内部結合
・how=’outer’ → 外部結合
・how=’left’ → 左結合(デフォルト)
・how=’right’ → 右結合

ここで、2つのデータに重複した列名が存在するとややこしくなるので、df2からname列を削除したdf3を使用して説明します。

#簡単のため、df2からnameを削除したdf3を用いる。
df3 = df2.drop('name', axis=1)
df3
DataFrame11

df1とdf3を結合する例を見て、それぞれの結合方法の違いを確認してみましょう。

#インデックスによる左結合(デフォルト)
df1.join(df3)

#df1:
#        name         city
#ID                       
#100    Alice     New York
#101      Bob  Los Angeles
#102  Charlie     New York
#104     Emma      Houston
#106    Grace  Los Angeles
#107     Hana      Chicago

#df3:
#     age
#ID      
#100   24
#101   35
#102   22
#103   56
#104   47
#105   38
DataFrame12
#インデックスによる右結合
df1.join(df3, how='right')

#df1:
#        name         city
#ID                       
#100    Alice     New York
#101      Bob  Los Angeles
#102  Charlie     New York
#104     Emma      Houston
#106    Grace  Los Angeles
#107     Hana      Chicago

#df3:
#     age
#ID      
#100   24
#101   35
#102   22
#103   56
#104   47
#105   38
DataFrame13
#インデックスによる内部結合
df1.join(df3, how='inner')

#df1:
#        name         city
#ID                       
#100    Alice     New York
#101      Bob  Los Angeles
#102  Charlie     New York
#104     Emma      Houston
#106    Grace  Los Angeles
#107     Hana      Chicago

#df3:
#     age
#ID      
#100   24
#101   35
#102   22
#103   56
#104   47
#105   38
DataFrame14
#インデックスによる外部結合
df1.join(df3, how='outer')

#df1:
#        name         city
#ID                       
#100    Alice     New York
#101      Bob  Los Angeles
#102  Charlie     New York
#104     Emma      Houston
#106    Grace  Los Angeles
#107     Hana      Chicago

#df3:
#     age
#ID      
#100   24
#101   35
#102   22
#103   56
#104   47
#105   38
DataFrame15

引数lsuffix/rsuffix:重複した列名に接尾語を設定

先ほど「2つのデータに重複した列名が存在するとややこしくなる」と言いましたが、重複する列名があるとエラーが出てしまいます。

この問題を回避するには引数『lsuffix/rsuffix』を用いて列名に接尾語を設定します。

以下の例では、df1とdf2で重複する列名nameについて、df2(右側)のname列に接尾語「_r」を設定しています。

#右のデータ(df2)のnameに接尾語_rを付けて重複を回避
df1.join(df2, rsuffix='_r')

#df1:
#        name         city
#ID                       
#100    Alice     New York
#101      Bob  Los Angeles
#102  Charlie     New York
#104     Emma      Houston
#106    Grace  Los Angeles
#107     Hana      Chicago

#df2:
#        name  age
#ID               
#100    Alice   24
#101      Bob   35
#102  Charlie   22
#103    David   56
#104     Emma   47
#105    Frank   38
DataFrame16

13章の練習問題

以下の練習問題を解いてみましょう。

練習問題

問1. 本記事中で用いたdf1,df2,df3について、(1)~(4)を出力するプログラムを書いてください。

(1) df1とdf2を縦方向に外部結合したDataFrame(concat関数を用いて)
(2) df1とdf2を横方向に内部結合したDataFrame(concat関数を用いて)
(3) 「name」列をキーとしてdf1とdf2を内部結合したDataFrame(merge関数を用いて)
(4) インデックスをキーとしてdf1とdf3を右結合したDataFrame(joinメソッドを用いて)

解答

問1(クリックして解答を表示)

(1)

#(1)
pd.concat([df1, df2])
DataFrame17

(2)

#(2)
pd.concat([df1, df2], axis=1, join='inner')
DataFrame18

(3)

#(3)
pd.merge(df1, df2, on='name')
DataFrame19

(4)

#(4)
df1.join(df3, how='right')
DataFrame20

次のページへ

Pandasの階層型インデックス(マルチインデックス)をマスター! 前のページ|次のページ 14章ではPandasのDataFrameにおける『階層型インデックス』について解説しています。 ...