LEFT
| RIGHT
| FULL
)(INNER
| OUTER
)をパンダと結合する方法merge
? join
? concat
? update
?誰?何?なぜ?!... もっと。私はこれらの繰り返しの質問がパンダマージ機能の様々な面について尋ねるのを見ました。今日のマージとそのさまざまなユースケースに関する情報の大部分は、何十ものひどく、検索できない投稿にまたがって断片化されています。ここでの目的は、後世のためのいくつかのより重要な点を照合することです。
このQnAは、一般的なパンダの慣用句に関する一連の有用なユーザーガイドの次の記事です( ピボット に関するこの記事と 連結に関するこの記事を参照)。 、後で触れます)。
この投稿はnotで、 ドキュメント の代わりになることを意図しているので、それも読んでください!例のいくつかはそこから取られます。
この投稿の目的は、読者にパンダとのSQL風味のマージ、その使用方法、使用しない場合の入門書を提供することです。
特に、この投稿の内容は次のとおりです。
基本-結合の種類(左、右、外側、内側)
merge
およびjoin
の注目すべき代替品この投稿が通過しないもの:
注
ほとんどの例では、特に指定がない限り、さまざまな機能を示しながら、デフォルトでINNER JOIN操作が使用されます。さらに、ここですべてのDataFramesをコピーして複製できるため、それらを操作できます。また、クリップボードからDataFrameを読み取る方法については この投稿 を参照してください。
最後に、JOIN操作の視覚的な表現はすべて、Google Drawingsを使用して手書きされています。 here からのインスピレーション。
merge
の使い方を教えてください!セットアップ
np.random.seed(0)
left = pd.DataFrame({'key': ['A', 'B', 'C', 'D'], 'value': np.random.randn(4)})
right = pd.DataFrame({'key': ['B', 'D', 'E', 'F'], 'value': np.random.randn(4)})
left
key value
0 A 1.764052
1 B 0.400157
2 C 0.978738
3 D 2.240893
right
key value
0 B 1.867558
1 D -0.977278
2 E 0.950088
3 F -0.151357
簡単にするために、キー列には同じ名前が付けられています(今のところ)。
INNER JOINは、
注
これは、今後の数字とともに、すべてこの規則に従います。
- blueは、マージ結果に存在する行を示します
- redは、結果から除外された(削除された)行を示します
- greenは、結果でNaNに置き換えられた欠損値を示します
INNER JOINを実行するには、 pd.merge
を呼び出して、左側のDataFrame、右側のDataFrame、および結合キーを指定します。
pd.merge(left, right, on='key')
key value_x value_y
0 B 0.400157 1.867558
1 D 2.240893 -0.977278
これは、共通キー(この例では「B」と「D」)を共有するleft
とright
からの行のみを返します。
pandas(v0.21程度)の最近のバージョンでは、merge
が1次関数になったため、 DataFrame.merge
を呼び出すことができます。
left.merge(right, on='key')
# Or, if you want to be explicit
# left.merge(right, on='key', how='inner')
key value_x value_y
0 B 0.400157 1.867558
1 D 2.240893 -0.977278
LEFT OUTER JOIN、またはLEFT JOINは
これは、how='left'
を指定することで実行できます。
left.merge(right, on='key', how='left')
key value_x value_y
0 A 1.764052 NaN
1 B 0.400157 1.867558
2 C 0.978738 NaN
3 D 2.240893 -0.977278
ここでNaNの配置に注意してください。 how='left'
を指定すると、left
のキーのみが使用され、right
の欠落データはNaNに置き換えられます。
同様に、RIGHT OUTER JOIN、またはRIGHT JOIN ...
... how='right'
を指定:
left.merge(right, on='key', how='right')
key value_x value_y
0 B 0.400157 1.867558
1 D 2.240893 -0.977278
2 E NaN 0.950088
3 F NaN -0.151357
ここでは、right
のキーが使用され、left
の欠落データはNaNに置き換えられます。
最後に、FULL OUTER JOINに対して、
how='outer'
を指定します。
left.merge(right, on='key', how='outer')
key value_x value_y
0 A 1.764052 NaN
1 B 0.400157 1.867558
2 C 0.978738 NaN
3 D 2.240893 -0.977278
4 E NaN 0.950088
5 F NaN -0.151357
これは両方のフレームのキーを使用し、両方の行の欠落に対してNaNが挿入されます。
ドキュメントはこれらのさまざまなマージをうまくまとめています:
必要な場合LEFT-Exclude JOINsおよびRIGHT-Exclude JOINsステップ。
LEFT-Exclude JOINの場合、次のように表されます
LEFT OUTER JOINを実行してから、left
のみからの行をフィルタリング(除外!)して、
(left.merge(right, on='key', how='left', indicator=True)
.query('_merge == "left_only"')
.drop('_merge', 1))
key value_x value_y
0 A 1.764052 NaN
2 C 0.978738 NaN
どこで、
left.merge(right, on='key', how='left', indicator=True)
key value_x value_y _merge
0 A 1.764052 NaN left_only
1 B 0.400157 1.867558 both
2 C 0.978738 NaN left_only
3 D 2.240893 -0.977278 both
同様に、右を除くJOINの場合、
(left.merge(right, on='key', how='right', indicator=True)
.query('_merge == "right_only"')
.drop('_merge', 1))
key value_x value_y
2 E NaN 0.950088
3 F NaN -0.151357
最後に、左または右のキーのみを保持し、両方を保持しないマージを実行する必要がある場合(IOW、ANTI-JOINの実行) 、
同様の方法でこれを行うことができます—
(left.merge(right, on='key', how='outer', indicator=True)
.query('_merge != "both"')
.drop('_merge', 1))
key value_x value_y
0 A 1.764052 NaN
2 C 0.978738 NaN
4 E NaN 0.950088
5 F NaN -0.151357
キー列の名前が異なる場合(たとえば、left
にkeyLeft
があり、right
にkeyRight
の代わりにkey
がある場合は、left_on
を指定する必要があります。 on
の代わりに引数としてright_on
:
left2 = left.rename({'key':'keyLeft'}, axis=1)
right2 = right.rename({'key':'keyRight'}, axis=1)
left2
keyLeft value
0 A 1.764052
1 B 0.400157
2 C 0.978738
3 D 2.240893
right2
keyRight value
0 B 1.867558
1 D -0.977278
2 E 0.950088
3 F -0.151357
left2.merge(right2, left_on='keyLeft', right_on='keyRight', how='inner')
keyLeft value_x keyRight value_y
0 B 0.400157 B 1.867558
1 D 2.240893 D -0.977278
keyLeft
からleft
とkeyRight
からright
からkeyLeft
をマージする場合、keyRight
またはkeyLeft
のいずれか(両方ではない)のみが必要な場合出力では、予備ステップとしてインデックスを設定することから開始できます。
left3 = left2.set_index('keyLeft')
left3.merge(right2, left_index=True, right_on='keyRight')
value_x keyRight value_y
0 0.400157 B 1.867558
1 2.240893 D -0.977278
これを直前のコマンドの出力(left2.merge(right2, left_on='keyLeft', right_on='keyRight', how='inner')
の出力)と比較すると、DataFrames
が欠落していることがわかります。どのフレームのインデックスがキーとして設定されているかに基づいて、保持する列を把握できます。これは、たとえば、OUTER JOIN操作を実行するときに重要になる場合があります。
たとえば、考慮してください
right3 = right.assign(newcol=np.arange(len(right)))
right3
key value newcol
0 B 1.867558 0
1 D -0.977278 1
2 E 0.950088 2
3 F -0.151357 3
「new_val」のみをマージする必要がある場合(他の列は一切使用しない)、通常、マージする前に列をサブセット化することができます。
left.merge(right3[['key', 'newcol']], on='key')
key value newcol
0 B 0.400157 0
1 D 2.240893 1
LEFT OUTER JOINを実行している場合、よりパフォーマンスの高いソリューションにはmap
が含まれます。
# left['newcol'] = left['key'].map(right3.set_index('key')['newcol']))
left.assign(newcol=left['key'].map(right3.set_index('key')['newcol']))
key value newcol
0 A 1.764052 NaN
1 B 0.400157 0.0
2 C 0.978738 NaN
3 D 2.240893 1.0
前述のように、これは似ていますが、より高速です
left.merge(right3[['key', 'newcol']], on='key', how='left')
key value newcol
0 A 1.764052 NaN
1 B 0.400157 0.0
2 C 0.978738 NaN
3 D 2.240893 1.0
複数の列で結合するには、on
(または必要に応じてleft_on
とright_on
)のリストを指定します。
left.merge(right, on=['key1', 'key2'] ...)
または、イベントが異なる場合、
left.merge(right, left_on=['lkey1', 'lkey2'], right_on=['rkey1', 'rkey2'])
merge*
操作と関数merge
に加えて、 DataFrame.update
および DataFrame.combine_first
は、特定の場合に、あるDataFrameを別のDataFrameで更新するためにも使用されます。
pd.merge_ordered
は、順序付けされたJOINに便利な関数です。
pd.merge_asof
(読み取り:merge_asOf)は、approoximate結合に役立ちます。
このセクションでは、ごく基本的なことのみを取り上げ、あなたの食欲を刺激することのみを目的としています。その他の例とケースについては、 merge
、join
、およびconcat
のドキュメント および関数仕様へのリンクを参照してください。
merge
s)セットアップ
np.random.seed([3, 14])
left = pd.DataFrame({'value': np.random.randn(4)}, index=['A', 'B', 'C', 'D'])
right = pd.DataFrame({'value': np.random.randn(4)}, index=['B', 'D', 'E', 'F'])
left.index.name = right.index.name = 'idxkey'
left
value
idxkey
A -0.602923
B -0.402655
C 0.302329
D -0.524349
right
value
idxkey
B 0.543843
D 0.013135
E -0.326498
F 1.385076
通常、インデックスのマージは次のようになります。
left.merge(right, left_index=True, right_index=True)
value_x value_y
idxkey
B -0.402655 0.543843
D -0.524349 0.013135
インデックスに名前が付けられている場合、v0.23ユーザーはon
(または必要に応じてleft_on
とright_on
)にレベル名を指定することもできます。
left.merge(right, on='idxkey')
value_x value_y
idxkey
B -0.402655 0.543843
D -0.524349 0.013135
マージを実行するために、あるインデックスを使用し、別のカラムを使用することができます(そして非常に簡単です)。例えば、
left.merge(right, left_on='key1', right_index=True)
またはその逆(right_on=...
およびleft_index=True
)。
right2 = right.reset_index().rename({'idxkey' : 'colkey'}, axis=1)
right2
colkey value
0 B 0.543843
1 D 0.013135
2 E -0.326498
3 F 1.385076
left.merge(right2, left_index=True, right_on='colkey')
value_x colkey value_y
0 -0.402655 B 0.543843
1 -0.524349 D 0.013135
この特殊なケースでは、left
のインデックスに名前が付けられているため、次のようにleft_on
でインデックス名を使用することもできます。
left.merge(right2, left_on='idxkey', right_on='colkey')
value_x colkey value_y
0 -0.402655 B 0.543843
1 -0.524349 D 0.013135
DataFrame.join
これらに加えて、別の簡潔なオプションがあります。デフォルトでインデックスに結合するDataFrame.join
を使用できます。 DataFrame.join
はデフォルトでLEFT OUTER JOINを実行するため、ここではhow='inner'
が必要です。
left.join(right, how='inner', lsuffix='_x', rsuffix='_y')
value_x value_y
idxkey
B -0.402655 0.543843
D -0.524349 0.013135
lsuffix
はエラーになるので、rsuffix
引数とjoin
引数を指定する必要があることに注意してください。
left.join(right)
ValueError: columns overlap but no suffix specified: Index(['value'], dtype='object')
列名が同じであるため。名前が異なる場合、これは問題になりません。
left.rename(columns={'value':'leftvalue'}).join(right, how='inner')
leftvalue value
idxkey
B -0.402655 0.543843
D -0.524349 0.013135
pd.concat
最後に、インデックスベースの結合の代替として、pd.concat
を使用できます。
pd.concat([left, right], axis=1, sort=False, join='inner')
value value
idxkey
B -0.402655 0.543843
D -0.524349 0.013135
FULL OUTER JOINが必要な場合は、join='inner'
を省略します(デフォルト):
pd.concat([left, right], axis=1, sort=False)
value value
A -0.602923 NaN
B -0.402655 0.543843
C 0.302329 NaN
D -0.524349 0.013135
E NaN -0.326498
F NaN 1.385076
詳細については、 @ piRSquaredによるpd.concat
に関するこの正規の投稿 を参照してください。
merge
ing複数のDataFrames多くの場合、複数のDataFrameをマージするときに状況が発生します。単純に、これはmerge
呼び出しを連鎖することで実行できます。
df1.merge(df2, ...).merge(df3, ...)
ただし、これは多くのDataFrameですぐに手に負えなくなります。さらに、不明な数のDataFrameに対して一般化する必要がある場合があります。
ここでは、uniqueキーでの多方向結合のpd.concat
と、non-uniqueキーでの多方向結合のDataFrame.join
を紹介します。まず、セットアップ。
# Setup.
np.random.seed(0)
A = pd.DataFrame({'key': ['A', 'B', 'C', 'D'], 'valueA': np.random.randn(4)})
B = pd.DataFrame({'key': ['B', 'D', 'E', 'F'], 'valueB': np.random.randn(4)})
C = pd.DataFrame({'key': ['D', 'E', 'J', 'C'], 'valueC': np.ones(4)})
dfs = [A, B, C]
# Note, the "key" column values are unique, so the index is unique.
A2 = A.set_index('key')
B2 = B.set_index('key')
C2 = C.set_index('key')
dfs2 = [A2, B2, C2]
キー(ここでは、キーは列またはインデックスのいずれか)が一意である場合、pd.concat
を使用できます。 pd.concat
は、インデックス上のデータフレームを結合することに注意してください。
# merge on `key` column, you'll need to set the index before concatenating
pd.concat([
df.set_index('key') for df in dfs], axis=1, join='inner'
).reset_index()
key valueA valueB valueC
0 D 2.240893 -0.977278 1.0
# merge on `key` index
pd.concat(dfs2, axis=1, sort=False, join='inner')
valueA valueB valueC
key
D 2.240893 -0.977278 1.0
FULL OUTER JOINの場合はjoin='inner'
を省略します。 LEFTまたはRIGHT OUTER結合を指定できないことに注意してください(これらが必要な場合は、以下で説明するjoin
を使用してください)。
concat
は高速ですが、欠点があります。重複は処理できません。
A3 = pd.DataFrame({'key': ['A', 'B', 'C', 'D', 'D'], 'valueA': np.random.randn(5)})
pd.concat([df.set_index('key') for df in [A3, B, C]], axis=1, join='inner')
ValueError: Shape of passed values is (3, 4), indices imply (3, 2)
この状況では、join
を使用できます。一意でないキーを処理できるためです(join
はインデックスのDataFramesに参加します。フードの下でmerge
を呼び出し、LEFT OUTER JOINを実行します特に指定しない限り)。
# join on `key` column, set as the index first
# For inner join. For left join, omit the "how" argument.
A.set_index('key').join(
[df.set_index('key') for df in (B, C)], how='inner').reset_index()
key valueA valueB valueC
0 D 2.240893 -0.977278 1.0
# join on `key` index
A3.set_index('key').join([B2, C2], how='inner')
valueA valueB valueC
key
D 1.454274 -0.977278 1.0
D 0.761038 -0.977278 1.0