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


208

次のような2つのデータフレームがあるとします。

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

しかし、私は結合方法を使用しようとしていますが、これはかなり似ていると信じていました。

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: 

何が欠けていますか?


4
ここでは、特定の問題はあるmergeの列加入leftの列にはright何をしたいですが、これは、join(... on=[...])の列合流leftの索引キーにrightあなたが欲しいものではありません。詳細については、以下の私の回答を参照してください。
Matthias Fripp 2017

3
DataFrame.join()は常に、呼び出し元のインデックスまたはキー(onオプションで指定)をotherのインデックスと照合します。結合のインデックスを覚えておいてください。一方、merge()はより一般的なメソッドです。
Jiapeng Zhang

回答:


87

私は常に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

エラーは、マルチインデックスが上rightの長さと同じ深さであることを期待していることを示しているようですon。それは私にはある程度理にかなっています。セマンティクスが異なることを受け入れることができます。しかし、私はdf.joinと同じ動作を得ることができるかどうかを知りたいのですが
ムンク

346

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

データフレームは、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)の1つ以上の列に参加することができますdf2(デフォルト)またはのインデックスにdf2(とright_index=True)。
  2. 左のテーブルのルックアップ:デフォルトでdf1.join(df2)は、のインデックスdf1とのdf1.merge(df2)列を使用しますdf1df1.join(df2, on=key_or_keys)またはを指定することで上書きできますdf1.merge(df2, left_index=True)
  3. 左対内部結合:df1.join(df2)デフォルトで左結合を実行します(のすべての行を保持df1)が、df.mergeデフォルトでは内部結合を実行します(df1andの一致する行のみを返しますdf2)。

したがって、一般的なアプローチは、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)

19
これは間違いなく受け入れられる答えになるはずです!十分な説明をありがとう
Yohan Obadia

@Matthias Fripp、おそらくもっと経験豊富な人にとっては言うまでもありませんが、「右のテーブルのルックアップ:df1.join(df2)をdf1.join(df2、on = key_or_keys?にオーバーライドできますか?
spacedustpi

@spacedustpi、私はあなたがon=key_or_keys正しいテーブルで行が見つけられる方法を変更するために使用できると言っていると思います。ただし、実際にはそうではありません。on引数には、上の検索を変更し、左(テーブルdf1、インデックスからのカラム(複数可)へ)。ただし、この引数を使用しても、右側のテーブル(df2)はそのインデックスを介して照合されます。(上記の最後の例を参照してください。)
Matthias Fripp

パンダには、これらの状況に対処するためのいくつかのメソッドがあり、その中には、マージ、結合、追加、連結、結合、結合、最初の結合があります。これらをそれぞれ見て、どれがあなたの状況に最も適しているかを垣間見ることができます
xiaxio

13

それjoin()は便利な方法だと思います。試してみてくださいdf1.merge(df2)代わりに、ユーザーが指定することを可能にするleft_onright_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

このドキュメントから

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')

8

違いの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

それは正しいです。インデックス以外の列で2つのデータフレームをマージすると、新しいインデックスが取得されますが、両方のデータフレームのインデックスでマージすると、同じインデックスのデータフレームが取得されます。したがって、マージ後に同じインデックスを取得するには、両方のデータフレームの列(マージしたい列)をインデックスにして、新しく作成したインデックスのデータフレームをマージします。
hasan najeeb

非常に洞察力があります。インデックス作成は必要ありませんでしたが(通常はインデックスをリセットするだけです)、場合によっては大きな違いが生じる可能性があります。
アイリーン

4
  • 結合:デフォルトのインデックス(同じ列名の場合、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')

2

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.