web-dev-qa-db-ja.com

パンダでの結合とマージの違いは何ですか?

次のような2つのDataFrameがあるとします。

left = pd.DataFrame({'key1': ['foo', 'bar'], 'lval': [1, 2]})

right = pd.DataFrame({'key2': ['foo', 'bar'], 'rval': [4, 5]})

私はそれらをマージしたいので、次のようなものを試します:

pd.merge(left, right, left_on='key1', right_on='key2')

そして私は幸せです

    key1    lval    key2    rval
0   foo     1       foo     4
1   bar     2       bar     5

しかし、私はjoinメソッドを使用しようとしています。

left.join(right, on=['key1', 'key2'])

そして、私はこれを取得します:

//anaconda/lib/python2.7/site-packages/pandas/tools/merge.pyc in _validate_specification(self)
    406             if self.right_index:
    407                 if not ((len(self.left_on) == self.right.index.nlevels)):
--> 408                     raise AssertionError()
    409                 self.right_on = [None] * n
    410         Elif self.right_on is not None:

AssertionError: 

私は何が欠けていますか?

133
munk

私は常にインデックスでjoinを使用します:

import pandas as pd
left = pd.DataFrame({'key': ['foo', 'bar'], 'val': [1, 2]}).set_index('key')
right = pd.DataFrame({'key': ['foo', 'bar'], 'val': [4, 5]}).set_index('key')
left.join(right, lsuffix='_l', rsuffix='_r')

     val_l  val_r
key            
foo      1      4
bar      2      5

以下の列でmergeを使用すると、同じ機能を使用できます。

left = pd.DataFrame({'key': ['foo', 'bar'], 'val': [1, 2]})
right = pd.DataFrame({'key': ['foo', 'bar'], 'val': [4, 5]})
left.merge(right, on=('key'), suffixes=('_l', '_r'))

   key  val_l  val_r
0  foo      1      4
1  bar      2      5
63
Paul H

pandas.merge()は、すべてのマージ/結合動作に使用される基になる関数です。

DataFramesは、pandas.DataFrame.merge()の機能にアクセスする便利な方法として、pandas.DataFrame.join()およびpandas.merge()メソッドを提供します。たとえば、df1.merge(right=df2, ...)pandas.merge(left=df1, right=df2, ...)と同等です。

これらは、df.join()df.merge()の主な違いです。

  1. 右側のテーブルのルックアップ:df1.join(df2)は常にdf2のインデックスを介して結合しますが、df1.merge(df2)df2の1つ以上の列(デフォルト)またはdf2のインデックス(right_index=Trueを使用)に結合できます。
  2. 左テーブルのルックアップ:デフォルトでは、df1.join(df2)df1のインデックスを使用し、df1.merge(df2)df1の列を使用します。 df1.join(df2, on=key_or_keys)またはdf1.merge(df2, left_index=True)を指定することで上書きできます。
  3. 左対内部結合:df1.join(df2)はデフォルトで左結合を行います(df1のすべての行を保持します)が、df.mergeはデフォルトで内部結合を行います(一致するdf1df2の行のみを返します)。

したがって、一般的なアプローチはpandas.merge(df1, df2)またはdf1.merge(df2)を使用することです。しかし、多くの一般的な状況(df1のすべての行を保持し、df2のインデックスに参加する場合)では、代わりにdf1.join(df2)を使用して入力を節約できます。

http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging のドキュメントからこれらの問題に関するいくつかのメモ

mergeはpandas名前空間の関数であり、DataFrameインスタンスメソッドとしても使用できます。呼び出し側のDataFrameは、暗黙的に結合の左側のオブジェクトと見なされます。

関連するDataFrame.joinメソッドは、インデックスオンインデックス結合およびインデックスオンカラム結合のために内部でmergeを使用しますが、共通カラムで結合しようとするのではなく、デフォルトでインデックスで結合します(mergeのデフォルトの動作)。インデックスに参加している場合は、DataFrame.joinを使用して入力を節約できます。

...

これら2つの関数呼び出しは完全に同等です。

left.join(right, on=key_or_keys)
pd.merge(left, right, left_on=key_or_keys, right_index=True, how='left', sort=False)
221
Matthias Fripp

join()は単なる便利なメソッドだと思います。代わりにdf1.merge(df2)を試してください。これにより、left_onおよびright_onを指定できます。

In [30]: left.merge(right, left_on="key1", right_on="key2")
Out[30]: 
  key1  lval key2  rval
0  foo     1  foo     4
1  bar     2  bar     5
11
Noah

http://pandas.pydata.org/pandas-docs/stable/merging.html#brief-primer-on-merge-methods-relational-algebra

pandasは、DataFrameオブジェクト間のすべての標準データベース結合操作のエントリポイントとして、単一の機能mergeを提供します。

merge(left、right、how = 'inner'、on = None、left_on = None、right_on = None、left_index = False、right_index = False、sort = True、suffixes =( '_ x'、 '_y')、copy = True、indicator = False)

そして:

DataFrame.joinは、インデックスが異なる可能性のある2つのDataFrameの列を1つの結果のDataFrameに結合する便利な方法です。非常に基本的な例を次に示します。ここでのデータの配置は、インデックス(行ラベル)に基づいています。この同じ動作は、マージとインデックスを使用するように指示する追加の引数を使用して実現できます:result = pd.merge(left、right、left_index = True、right_index = True、how = 'outer')

7
Romain Jouin

違いの1つは、mergeが新しいインデックスを作成し、joinが左側のインデックスを保持していることです。 mergeを使用してインデックスが変更されないと誤って想定した場合、後の変換に大きな影響を与える可能性があります。

例えば:

import pandas as pd

df1 = pd.DataFrame({'org_index': [101, 102, 103, 104],
                    'date': [201801, 201801, 201802, 201802],
                    'val': [1, 2, 3, 4]}, index=[101, 102, 103, 104])
df1

       date  org_index  val
101  201801        101    1
102  201801        102    2
103  201802        103    3
104  201802        104    4

-

df2 = pd.DataFrame({'date': [201801, 201802], 'dateval': ['A', 'B']}).set_index('date')
df2

       dateval
date          
201801       A
201802       B

-

df1.merge(df2, on='date')

     date  org_index  val dateval
0  201801        101    1       A
1  201801        102    2       A
2  201802        103    3       B
3  201802        104    4       B

-

df1.join(df2, on='date')
       date  org_index  val dateval
101  201801        101    1       A
102  201801        102    2       A
103  201802        103    3       B
104  201802        104    4       B
3
steco

SQLの「パンダのマージは外部/内部の結合であり、Pandasの結合は自然な結合です」と同様です。したがって、pandasでマージを使用する場合は、使用するsqlish結合の種類を指定する必要がありますが、pandas joinを使用する場合は、一致する列ラベルを使用して結合する必要があります

1
Kaustubh J
  • 結合:デフォルトインデックス(同じ列名がある場合、lsuffixまたはrsuffixが定義されていないため、デフォルトモードでエラーがスローされます)
df_1.join(df_2)
  • マージ:デフォルトの同じ列名(同じ列名がない場合、デフォルトモードでエラーがスローされます)
df_1.merge(df_2)
  • onパラメーターは、両方の場合で異なる意味を持ちます
df_1.merge(df_2, on='column_1')

df_1.join(df_2, on='column_1') // It will throw error
df_1.join(df_2.set_index('column_1'), on='column_1')
1
Harsh