キーを使って複数のDataFrameを結合する|pandas.merge()

pandas.merge

共通のデータ列を持っている表 (DataFrame) を結合したいとき、panda.merge()関数が便利です。

pandas.merge()は共通するデータ列をキーとしてDataFrameを列(横)方向に結合します。

この記事ではpandas.mergeの使い方についてわかりやすく説明します。

目次

pandas.merge()とは

pandas.merge()とは

pandas.merge()とは複数のDataFrameを列方向に結合する関数です。

pandas.merge 【pandas公式】

共通する列データをキーとして結合してくれるので、例えば「1組と2組のテスト結果を1つにまとめたい」のように、共通の列データを持つDataFrameを結合したいときに便利です。

本記事のコードは全てグーグルコラボラトリーで記述・動作を確認しています。

グーグルコラボラトリーとはgoogleアカウントを持っている人であれば、誰でも・無料で使うことができるpythonの対話型実行環境です。

データ分析に必要なライブラリが初めから搭載されていて、環境構築の必要がないため、python初心者には特にオススメです!

pandas.merge()の使い方

pandas.merge()の使い方

準備

始めにpandasをインポートしましょう。

import pandas as pd

次に今回使用するDataFrame(表)を用意します。用意したDataFrameは7人のテスト結果です。

df1 = pd.DataFrame({'科目': ['国語', '数学', '英語'],
                    'A': [51, 21, 14],
                    'B': [70, 0, 74],
                    'C': [35, 55, 23],
                    'D': [90, 50,67]})

df2 = pd.DataFrame({'科目': ['国語', '数学', '英語'],
                    'E': [100, 92, 44],
                    'F': [6, 22, 29],
                    'G': [34,53, 20]})

df3 = pd.DataFrame({'科目': ['国語', '英語', '理科', '社会'],
                    'E': [100, 44, 44, 61],
                    'F': [6, 29, 2, 50],
                    'G': [34, 20, 43, 32]})

df4 = pd.DataFrame({'科目': ['国語', '数学', '英語'],
                    'D': [90, 50,67], 
                    'E': [100, 92, 44],
                    'F': [6, 22, 29],
                    'G': [34,53, 20]})
df1

出力:

index科目ABCD
0国語51703590
1数学2105550
2英語14742367
df1
df2

出力:

index科目EFG
0国語100634
1数学922253
2英語442920
df2
df3

出力:

index科目EFG
0国語100634
1英語442920
2理科44243
3社会615032
df3
df4

出力:

index科目DEFG
0国語90100634
1数学50922253
2英語67442920
df4

基本的な使い方

pandas.merge()はカッコの中に、右側にしたいDataFrameと左側にしたいDataFrameを指定することで結合できます。

このとき両方のDataFrameに共通する列をキーとします。

#pandas.merge(左側にしたいdataframe, 右側にしたいdataframe)
pd.merge(df1, df2)

出力:

index科目ABCDEFG
0国語51703590100634
1数学2105550922253
2英語14742367442920
pandas.merge(df1, df2)

今回のデータだと、2つのdataframeに共通していた’科目’列がキーとなったため、df2にあった’科目’列が自動で削除されていることが確認できます。

pandas.merge()は列を横に結合する事はできますが、行を縦に結合することはできません。
縦や横に行や列を結合したい場合はpandas.concat()関数を使用しましょう。

また、df1.merge(df2)と記述しても同じようにDataFrameの結合が可能です。

#左側にしたいdataframe.merge(右側にしたいdataframe)
df1.merge(df2)

出力:

index科目ABCDEFG
0国語51703590100634
1数学2105550922253
2英語14742367442920
df1.merge(df2)

結合方法の指定: how

ここからはpandas.merge()に備わっている引数を説明していきます。

引数 ‘how’ を指定することで、dataframeの結合方法を変えられます。デフォルトは ‘inner’ です。

  • inner: 両方に共通するキーのみ返す。
  • outer: 全てのキーを返す。
  • left: 左のDataFrameのキーのみ返す。
  • right: 右のDataFrameのキーのみを返す。

結合方法の指定とは、キーが異なるDataFrameをどのように結合するか指定することです。

df1とdf3の結合を試してみましょう。これらのDataFrameには次のような関係があります。

  • 国語と英語の行は両方にある。
  • 数学の行はdf1にのみある。
  • 理科・社会の行はdf3にのみある。

それぞれの結合方法で結合してみましょう。

pd.merge(df1, df5, how='inner')

出力:

index科目ABCDEFG
0国語51703590100634
1英語14742367442920
how=’inner’

how=’inner’ではdf1とdf3に共通する’国語’、’英語’の行のみが結合して返されました。

pd.merge(df1, df3, how='outer')

出力:

index科目ABCDEFG
0国語51.070.035.090.0100.06.034.0
1数学21.00.055.050.0NaNNaNNaN
2英語14.074.023.067.044.029.020.0
3理科NaNNaNNaNNaN44.02.043.0
4社会NaNNaNNaNNaN61.050.032.0
how=’outer’

how=’outer’では全部の行が返されました。A、B、Cの理科、社会とF、E、Gの数学データはNaN(欠損値)になっています。

pd.merge(df1, df3, how='left')

出力:

index科目ABCDEFG
0国語51703590100.06.034.0
1数学2105550NaNNaNNaN
2英語1474236744.029.020.0
how=’left’

how=’left’では、pandas.merge()で左に指定したdf1に合わせて、国語、数学、英語のデータが出力されました。df3に’数学’行がないので、NaNになっています。

pd.merge(df1, df3, how='right')

出力:

index科目ABCDEFG
0国語51.070.035.090.0100634
1英語14.074.023.067.0442920
2理科NaNNaNNaNNaN44243
3社会NaNNaNNaNNaN615032
how=’right’

how=’right’では、右側に指定したdf3に合わせて、国語、英語、理科、社会のデータが出力されました。 df1に理科と社会のデータがないので、NaNで出力されてます。

キーとなる列を指定: on, left_on, right_on

引数 ‘on’ を使用することで、キーとなる列を指定できます。

pandas.mergeは共通する列名をキーとして結合すると説明しました。今回のデータでは’科目’が共通するため、キーとして使われていますね。

df1とdf4を結合してみましょう。両方に’科目’と’D’の列名が共通しています。

pd.merge(df1, df4)

出力:

index科目ABCDEFG
0国語51703590100634
1数学2105550922253
2英語14742367442920
pandas.merge(df1, df4)

引数を指定しない場合、共通する’科目’と’D’列の両方がキーとして使われています。

見た目ではpandas.merge(df1, df2)と同じに見えますね。

共通する列名が2つ以上ある場合、引数onでキーとなる列名を指定することが可能です。このとき、キーとならなかった列名は後ろに ‘_x’, ‘_y’ が追加されて結合されます。

pd.merge(df1, df4, on='科目')

出力:

index科目ABCD_xD_yEFG
0国語5170359090100634
1数学210555050922253
2英語1474236767442920
on=’科目’

共通するキーが1つだけだったとしても、引数 ‘on ‘は使用できます。記述することでコードが読みやすくなる場合があります。

ところで、pandas.merge()は共通する列データをキーとして結合すると説明しました。

では、共通する列データがない場合はどうなるのでしょう?

df2の’科目’という列名を’教科’に変更したdf5を用意し、試してみます。

df5 = df2.rename(columns={'科目': '教科'})
df5

出力:

index教科EFG
0国語100634
1数学922253
2英語442920
df5
pd.merge(df1, df5)

出力:

MergeError: No common columns to perform merge on. Merge options: left_on=None, right_on=None, left_index=False, right_index=False

エラーになってしまいました。

共通する列名がないときは、引数’left_on’ と ‘right_on’ で指定してあげることで結合可能です。

pd.merge(df1, df5, left_on='科目', right_on='教科')
index科目ABCD教科EFG
0国語51703590国語100634
1数学2105550数学922253
2英語14742367英語442920
left_on, right_on

途中にある列 ‘教科’のせいで見づらいですね。そんな時はdrop()関数で削除しましょう。

pd.merge(df1, df5, left_on='科目', right_on='教科').drop(columns='教科')

出力:

index科目ABCDEFG
0国語51703590100634
1数学2105550922253
2英語14742367442920
drop(columns=’教科’)

重複する列名がある場合:suffixes

キー以外に列名が共通している列がある場合、その列名は ‘_x’, ‘_y’ が追加されて結合されることを引数 ‘on’の時に説明しました。

‘_x’, ‘_y’ 以外のサフィックスを指定したい場合、引数 ‘suffixes’ に左側のサフィックス、右側のサフィックスを指定します。

pd.merge(df1, df4, on='科目', suffixes=['_a', '_b'])

出力:

index科目ABCD_aD_bEFG
0国語5170359090100634
1数学210555050922253
2英語1474236767442920
引数 ‘suffixes’

キーでソートする:sort

キーでソートしたい場合、引数’sort’ をTrueとしましょう。

pd.merge(df1, df4, on='D', sort=True)

Dの点数でソートされました。

indexをキーに指定する: left_index, right_index

indexをキーにしたい場合、引数 ‘left_index’, ‘right_index’ でキーがindexにある側をTrueで指定することで、結合可能です。

df2のindexを’0, 1, 2’から’国語, 数学, 英語’に変更したdf2_iを用意します。

df2_i = df2.set_index('科目')
df2_i

出力:

科目EFG
国語100634
数学922253
英語442920
df2_i

今回はdf2_iを右側で結合するので、right_index=Trueを記述します。左側で結合する際は引数 ‘left_index’ で指定します。

pd.merge(df1, df2_i, left_on='科目', right_index=True)

出力:

index科目ABCDEFG
0国語51703590100634
1数学2105550922253
2英語14742367442920
right_index=True

結合に使用したdataframeの情報を追加: indicator

引数 ‘indicator’ をTrueにすると、結合に使用したdataframeの情報を追加できます。右側のみに値があった列は right_only、左側のみに値があった列は left_only 、両方に値があった列は both と分類されます。

引数 ‘how’ で使用した、pandas.merge(df1, df3)で確認してみましょう。

pd.merge(df1, df3, how='outer', indicator=True)

出力:

index科目ABCDEFG_merge
0国語51.070.035.090.0100.06.034.0both
1数学21.00.055.050.0NaNNaNNaNleft_only
2英語14.074.023.067.044.029.020.0both
3理科NaNNaNNaNNaN44.02.043.0right_only
4社会NaNNaNNaNNaN61.050.032.0right_only
indicator=True

引数 ‘indicator’ に文字列を指定すると、列名 ‘_merge’ が指定した文字列になります。

pd.merge(df1, df3, how='outer', indicator='check')

出力:

index科目ABCDEFGcheck
0国語51.070.035.090.0100.06.034.0both
1数学21.00.055.050.0NaNNaNNaNleft_only
2英語14.074.023.067.044.029.020.0both
3理科NaNNaNNaNNaN44.02.043.0right_only
4社会NaNNaNNaNNaN61.050.032.0right_only
indicator=’check’

まとめ

今回はpandas.merge()関数について紹介しました。

pandas.merge()はDataFrameを横に結合させたい時におすすめの関数です。

この記事を読んで、もっとpythonについて勉強したくなった人にはこちらの記事もおすすめです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次