web-dev-qa-db-ja.com

pandas mergeの "left_index"および "right_index"引数を理解する

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

ご覧のとおり、key1key2の右側のフレームに関するすべての情報が完全に失われています。

これらの議論の目的と機能を理解するのを手伝ってください。ありがとうございました。

5
ste_kwr

mergeの動作を正しく理解している場合は、leftrightに対してそれぞれ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

ここまで読んでいただければ、複数の異なる方法を使用して上記を達成する方法を知っていると確信しています。お役に立てれば。

1
gyoza