Pandas.mergeの「left_index」と「right_index」の引数を理解するのに本当に苦労しています。ドキュメントを読み、検索し、さまざまな設定を試し、理解しようとしましたが、それでも混乱しています。この例を考えてみましょう。
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
'key2': ['K0', 'K1', 'K0', 'K1'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
'key2': ['K0', 'K0', 'K0', 'K0'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3'],
'E': [1,2,3,4]})
ここで、次のコマンドを実行すると、次のようになります。
pd.merge(left, right, left_on=['key2', 'key1'], right_on=['key1', 'key2'], how='outer', indicator=True, left_index=True)
私は得る:
key1_x key2_x A B key1_y key2_y C D E _merge
0 K0 K0 A0 B0 K0 K0 C0 D0 1.0 both
1 K0 K1 A1 B1 K1 K0 C1 D1 2.0 both
2 K0 K1 A1 B1 K1 K0 C2 D2 3.0 both
3 K1 K0 A2 B2 NaN NaN NaN NaN NaN left_only
3 K2 K1 A3 B3 NaN NaN NaN NaN NaN left_only
3 NaN NaN NaN NaN K2 K0 C3 D3 4.0 right_only
ただし、同じものをright_index=True
で実行すると、エラーが発生します。両方紹介しても同じです。さらに興味深いことに、次のマージを実行すると、非常に予期しない結果が得られます
pd.merge(left, right, on=['key1', 'key2'],how='outer', validate = 'one_to_many', indicator=True, left_index = True, right_index = True)
結果は次のとおりです。
key1 key2 A B C D E _merge
0 K0 K0 A0 B0 C0 D0 1 both
1 K0 K1 A1 B1 C1 D1 2 both
2 K1 K0 A2 B2 C2 D2 3 both
3 K2 K1 A3 B3 C3 D3 4 both
ご覧のとおり、key1
とkey2
の右側のフレームに関するすべての情報が完全に失われています。
これらの議論の目的と機能を理解するのを手伝ってください。ありがとうございました。
merge
の動作を正しく理解している場合は、left
とright
に対してそれぞれ1つのオプションのみを選択する必要があります(つまり、あなたすべきではない pick left_on=['x']
とleft_index=True
を同時に)。そうしないと、merge
の現在の実装で示したように、実際にどのkey
を使用すべきかについてmerge
を混乱させるため、奇妙なことが任意の方法で発生する可能性があります(私はチェックしていません) pandasソースの詳細ですが、バージョンごとに実装が異なると動作が変わる可能性があります)。これは小さな実験です。
>>> left
key1 key2 A B
0 K0 K0 A0 B0
1 K0 K1 A1 B1
2 K1 K0 A2 B2
3 K2 K1 A3 B3
>>> right
key1 key2 C D E
0 K0 K0 C0 D0 1
1 K1 K0 C1 D1 2
2 K1 K0 C2 D2 3
3 K2 K0 C3 D3 4
(1)merge
using ['key1', 'key2']
>>> pd.merge(left, right, on=['key1', 'key2'], how='outer')
key1 key2 A B C D E
0 K0 K0 A0 B0 C0 D0 1.0
1 K0 K1 A1 B1 NaN NaN NaN
2 K1 K0 A2 B2 C1 D1 2.0
3 K1 K0 A2 B2 C2 D2 3.0
4 K2 K1 A3 B3 NaN NaN NaN
5 K2 K0 NaN NaN C3 D3 4.0
(2)['key1', 'key2']
をleft
インデックスとして設定し、インデックスとキーを使用してmerge
に設定します
>>> left = left.set_index(['key1', 'key2'])
>>> pd.merge(left, right, left_index=True, right_on=['key1', 'key2'], how='outer').reset_index(drop=True)
A B key1 key2 C D E
0 A0 B0 K0 K0 C0 D0 1.0
1 A1 B1 K0 K1 NaN NaN NaN
2 A2 B2 K1 K0 C1 D1 2.0
3 A2 B2 K1 K0 C2 D2 3.0
4 A3 B3 K2 K1 NaN NaN NaN
5 NaN NaN K2 K0 C3 D3 4.0
(3)さらに['key1', 'key2']
をright
インデックスとして設定し、merge
インデックスを使用して設定します
>>> right = right.set_index(['key1', 'key2'])
>>> pd.merge(left, right, left_index=True, right_index=True, how='outer').reset_index()
key1 key2 A B C D E
0 K0 K0 A0 B0 C0 D0 1.0
1 K0 K1 A1 B1 NaN NaN NaN
2 K1 K0 A2 B2 C1 D1 2.0
3 K1 K0 A2 B2 C2 D2 3.0
4 K2 K0 NaN NaN C3 D3 4.0
5 K2 K1 A3 B3 NaN NaN NaN
上記の(1)(2)(3)でも同じ結果が得られ、['key1', 'key2']
がインデックスとして設定されていても、left_on = ['key1', 'key2']
の代わりにleft_index=True
を使用できます。
さて、本当に['key1', 'key2']
とindex
の両方を使用してマージしたい場合、これを実現する1つの方法は次のとおりです。
>>> pd.merge(left.reset_index(), right.reset_index(), on=['index', 'key1', 'key2'], how='outer')
index key1 key2 A B C D E
0 0 K0 K0 A0 B0 C0 D0 1.0
1 1 K0 K1 A1 B1 NaN NaN NaN
2 2 K1 K0 A2 B2 C2 D2 3.0
3 3 K2 K1 A3 B3 NaN NaN NaN
4 1 K1 K0 NaN NaN C1 D1 2.0
5 3 K2 K0 NaN NaN C3 D3 4.0
ここまで読んでいただければ、複数の異なる方法を使用して上記を達成する方法を知っていると確信しています。お役に立てれば。