共通のデータ列を持っている表 (DataFrame) を結合したいとき、panda.merge()関数が便利です。
pandas.merge()は共通するデータ列をキーとしてDataFrameを列(横)方向に結合します。
この記事ではpandas.mergeの使い方についてわかりやすく説明します。
pandas.merge()とは
pandas.merge()とは複数のDataFrameを列方向に結合する関数です。
共通する列データをキーとして結合してくれるので、例えば「1組と2組のテスト結果を1つにまとめたい」のように、共通の列データを持つDataFrameを結合したいときに便利です。
本記事のコードは全てグーグルコラボラトリーで記述・動作を確認しています。
グーグルコラボラトリーとはgoogleアカウントを持っている人であれば、誰でも・無料で使うことができるpythonの対話型実行環境です。
データ分析に必要なライブラリが初めから搭載されていて、環境構築の必要がないため、python初心者には特にオススメです!
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 | 科目 | A | B | C | D |
---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 |
1 | 数学 | 21 | 0 | 55 | 50 |
2 | 英語 | 14 | 74 | 23 | 67 |
df2
出力:
index | 科目 | E | F | G |
---|---|---|---|---|
0 | 国語 | 100 | 6 | 34 |
1 | 数学 | 92 | 22 | 53 |
2 | 英語 | 44 | 29 | 20 |
df3
出力:
index | 科目 | E | F | G |
---|---|---|---|---|
0 | 国語 | 100 | 6 | 34 |
1 | 英語 | 44 | 29 | 20 |
2 | 理科 | 44 | 2 | 43 |
3 | 社会 | 61 | 50 | 32 |
df4
出力:
index | 科目 | D | E | F | G |
---|---|---|---|---|---|
0 | 国語 | 90 | 100 | 6 | 34 |
1 | 数学 | 50 | 92 | 22 | 53 |
2 | 英語 | 67 | 44 | 29 | 20 |
基本的な使い方
pandas.merge()はカッコの中に、右側にしたいDataFrameと左側にしたいDataFrameを指定することで結合できます。
このとき両方のDataFrameに共通する列をキーとします。
#pandas.merge(左側にしたいdataframe, 右側にしたいdataframe)
pd.merge(df1, df2)
出力:
index | 科目 | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 | 100 | 6 | 34 |
1 | 数学 | 21 | 0 | 55 | 50 | 92 | 22 | 53 |
2 | 英語 | 14 | 74 | 23 | 67 | 44 | 29 | 20 |
今回のデータだと、2つのdataframeに共通していた’科目’列がキーとなったため、df2にあった’科目’列が自動で削除されていることが確認できます。
pandas.merge()は列を横に結合する事はできますが、行を縦に結合することはできません。
縦や横に行や列を結合したい場合はpandas.concat()関数を使用しましょう。
また、df1.merge(df2)と記述しても同じようにDataFrameの結合が可能です。
#左側にしたいdataframe.merge(右側にしたいdataframe)
df1.merge(df2)
出力:
index | 科目 | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 | 100 | 6 | 34 |
1 | 数学 | 21 | 0 | 55 | 50 | 92 | 22 | 53 |
2 | 英語 | 14 | 74 | 23 | 67 | 44 | 29 | 20 |
結合方法の指定: 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 | 科目 | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 | 100 | 6 | 34 |
1 | 英語 | 14 | 74 | 23 | 67 | 44 | 29 | 20 |
how=’inner’ではdf1とdf3に共通する’国語’、’英語’の行のみが結合して返されました。
pd.merge(df1, df3, how='outer')
出力:
index | 科目 | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|---|
0 | 国語 | 51.0 | 70.0 | 35.0 | 90.0 | 100.0 | 6.0 | 34.0 |
1 | 数学 | 21.0 | 0.0 | 55.0 | 50.0 | NaN | NaN | NaN |
2 | 英語 | 14.0 | 74.0 | 23.0 | 67.0 | 44.0 | 29.0 | 20.0 |
3 | 理科 | NaN | NaN | NaN | NaN | 44.0 | 2.0 | 43.0 |
4 | 社会 | NaN | NaN | NaN | NaN | 61.0 | 50.0 | 32.0 |
how=’outer’では全部の行が返されました。A、B、Cの理科、社会とF、E、Gの数学データはNaN(欠損値)になっています。
pd.merge(df1, df3, how='left')
出力:
index | 科目 | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 | 100.0 | 6.0 | 34.0 |
1 | 数学 | 21 | 0 | 55 | 50 | NaN | NaN | NaN |
2 | 英語 | 14 | 74 | 23 | 67 | 44.0 | 29.0 | 20.0 |
how=’left’では、pandas.merge()で左に指定したdf1に合わせて、国語、数学、英語のデータが出力されました。df3に’数学’行がないので、NaNになっています。
pd.merge(df1, df3, how='right')
出力:
index | 科目 | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|---|
0 | 国語 | 51.0 | 70.0 | 35.0 | 90.0 | 100 | 6 | 34 |
1 | 英語 | 14.0 | 74.0 | 23.0 | 67.0 | 44 | 29 | 20 |
2 | 理科 | NaN | NaN | NaN | NaN | 44 | 2 | 43 |
3 | 社会 | NaN | NaN | NaN | NaN | 61 | 50 | 32 |
how=’right’では、右側に指定したdf3に合わせて、国語、英語、理科、社会のデータが出力されました。 df1に理科と社会のデータがないので、NaNで出力されてます。
キーとなる列を指定: on, left_on, right_on
引数 ‘on’ を使用することで、キーとなる列を指定できます。
pandas.mergeは共通する列名をキーとして結合すると説明しました。今回のデータでは’科目’が共通するため、キーとして使われていますね。
df1とdf4を結合してみましょう。両方に’科目’と’D’の列名が共通しています。
pd.merge(df1, df4)
出力:
index | 科目 | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 | 100 | 6 | 34 |
1 | 数学 | 21 | 0 | 55 | 50 | 92 | 22 | 53 |
2 | 英語 | 14 | 74 | 23 | 67 | 44 | 29 | 20 |
引数を指定しない場合、共通する’科目’と’D’列の両方がキーとして使われています。
見た目ではpandas.merge(df1, df2)と同じに見えますね。
共通する列名が2つ以上ある場合、引数onでキーとなる列名を指定することが可能です。このとき、キーとならなかった列名は後ろに ‘_x’, ‘_y’ が追加されて結合されます。
pd.merge(df1, df4, on='科目')
出力:
index | 科目 | A | B | C | D_x | D_y | E | F | G |
---|---|---|---|---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 | 90 | 100 | 6 | 34 |
1 | 数学 | 21 | 0 | 55 | 50 | 50 | 92 | 22 | 53 |
2 | 英語 | 14 | 74 | 23 | 67 | 67 | 44 | 29 | 20 |
共通するキーが1つだけだったとしても、引数 ‘on ‘は使用できます。記述することでコードが読みやすくなる場合があります。
ところで、pandas.merge()は共通する列データをキーとして結合すると説明しました。
では、共通する列データがない場合はどうなるのでしょう?
df2の’科目’という列名を’教科’に変更したdf5を用意し、試してみます。
df5 = df2.rename(columns={'科目': '教科'})
df5
出力:
index | 教科 | E | F | G |
---|---|---|---|---|
0 | 国語 | 100 | 6 | 34 |
1 | 数学 | 92 | 22 | 53 |
2 | 英語 | 44 | 29 | 20 |
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 | 科目 | A | B | C | D | 教科 | E | F | G |
---|---|---|---|---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 | 国語 | 100 | 6 | 34 |
1 | 数学 | 21 | 0 | 55 | 50 | 数学 | 92 | 22 | 53 |
2 | 英語 | 14 | 74 | 23 | 67 | 英語 | 44 | 29 | 20 |
途中にある列 ‘教科’のせいで見づらいですね。そんな時はdrop()関数で削除しましょう。
pd.merge(df1, df5, left_on='科目', right_on='教科').drop(columns='教科')
出力:
index | 科目 | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 | 100 | 6 | 34 |
1 | 数学 | 21 | 0 | 55 | 50 | 92 | 22 | 53 |
2 | 英語 | 14 | 74 | 23 | 67 | 44 | 29 | 20 |
重複する列名がある場合:suffixes
キー以外に列名が共通している列がある場合、その列名は ‘_x’, ‘_y’ が追加されて結合されることを引数 ‘on’の時に説明しました。
‘_x’, ‘_y’ 以外のサフィックスを指定したい場合、引数 ‘suffixes’ に左側のサフィックス、右側のサフィックスを指定します。
pd.merge(df1, df4, on='科目', suffixes=['_a', '_b'])
出力:
index | 科目 | A | B | C | D_a | D_b | E | F | G |
---|---|---|---|---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 | 90 | 100 | 6 | 34 |
1 | 数学 | 21 | 0 | 55 | 50 | 50 | 92 | 22 | 53 |
2 | 英語 | 14 | 74 | 23 | 67 | 67 | 44 | 29 | 20 |
キーでソートする: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
出力:
科目 | E | F | G |
---|---|---|---|
国語 | 100 | 6 | 34 |
数学 | 92 | 22 | 53 |
英語 | 44 | 29 | 20 |
今回はdf2_iを右側で結合するので、right_index=Trueを記述します。左側で結合する際は引数 ‘left_index’ で指定します。
pd.merge(df1, df2_i, left_on='科目', right_index=True)
出力:
index | 科目 | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 | 100 | 6 | 34 |
1 | 数学 | 21 | 0 | 55 | 50 | 92 | 22 | 53 |
2 | 英語 | 14 | 74 | 23 | 67 | 44 | 29 | 20 |
結合に使用したdataframeの情報を追加: indicator
引数 ‘indicator’ をTrueにすると、結合に使用したdataframeの情報を追加できます。右側のみに値があった列は right_only、左側のみに値があった列は left_only 、両方に値があった列は both と分類されます。
引数 ‘how’ で使用した、pandas.merge(df1, df3)で確認してみましょう。
pd.merge(df1, df3, how='outer', indicator=True)
出力:
index | 科目 | A | B | C | D | E | F | G | _merge |
---|---|---|---|---|---|---|---|---|---|
0 | 国語 | 51.0 | 70.0 | 35.0 | 90.0 | 100.0 | 6.0 | 34.0 | both |
1 | 数学 | 21.0 | 0.0 | 55.0 | 50.0 | NaN | NaN | NaN | left_only |
2 | 英語 | 14.0 | 74.0 | 23.0 | 67.0 | 44.0 | 29.0 | 20.0 | both |
3 | 理科 | NaN | NaN | NaN | NaN | 44.0 | 2.0 | 43.0 | right_only |
4 | 社会 | NaN | NaN | NaN | NaN | 61.0 | 50.0 | 32.0 | right_only |
引数 ‘indicator’ に文字列を指定すると、列名 ‘_merge’ が指定した文字列になります。
pd.merge(df1, df3, how='outer', indicator='check')
出力:
index | 科目 | A | B | C | D | E | F | G | check |
---|---|---|---|---|---|---|---|---|---|
0 | 国語 | 51.0 | 70.0 | 35.0 | 90.0 | 100.0 | 6.0 | 34.0 | both |
1 | 数学 | 21.0 | 0.0 | 55.0 | 50.0 | NaN | NaN | NaN | left_only |
2 | 英語 | 14.0 | 74.0 | 23.0 | 67.0 | 44.0 | 29.0 | 20.0 | both |
3 | 理科 | NaN | NaN | NaN | NaN | 44.0 | 2.0 | 43.0 | right_only |
4 | 社会 | NaN | NaN | NaN | NaN | 61.0 | 50.0 | 32.0 | right_only |
まとめ
今回はpandas.merge()関数について紹介しました。
pandas.merge()はDataFrameを横に結合させたい時におすすめの関数です。
この記事を読んで、もっとpythonについて勉強したくなった人にはこちらの記事もおすすめです。
コメント