在熊猫中加入和合并有什么区别?


208

假设我有两个像这样的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: 

我想念什么?


4
此处的特定问题是,您想要的是merge将的列连接left到的列right,而您不需要的是join(... on=[...])将的列连接left到的索引键right。有关更多详细信息,请参见下面的答案。
马提亚斯·弗里普

3
DataFrame.join()始终希望将调用者的索引或键(由onoption 指定)与的索引进行匹配other。记住,连接索引。虽然merge()是一种更通用的方法。
张佳鹏

Answers:


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达到相同的效果
munk

345

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(默认)的一个或多个列或df2(与right_index=True)的索引进行连接。
  2. 在左表上查找:默认情况下,df1.join(df2)使用的索引df1df1.merge(df2)使用的列df1。可以通过指定df1.join(df2, on=key_or_keys)或覆盖df1.merge(df2, left_index=True)
  3. 左vs内部联接:df1.join(df2)默认情况下执行左联接(保留的所有行df1),但df.merge默认情况下进行内部联接(仅返回df1和的匹配行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来保存自己的输入内容。

...

这两个函数调用是完全等效的:

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

18
这绝对应该是公认的答案!感谢您的thourough解释
勒芒奥巴迪亚

@Matthias Fripp,也许对于经验丰富的人来说不用说了,但是也可以说“在右表上查找:df1.join(df2)可以覆盖为df1.join(df2,on = key_or_keys?
spacedustpi

@spacedustpi,我想您是说您可以on=key_or_keys用来更改在正确的表中找到行的方式。但是,实际上并非如此。该on参数将在表(df1)上的查找从索引更改为列。但是,即使使用此参数,右表(df2)也会通过其索引进行匹配。(请参见上面的最后一个示例。)
Matthias Fripp

熊猫有几种处理这些情况的方法,其中包括合并,连接,附加,连接,合并,combining_first。看一下其中的每一个,一眼就能看出哪一个最适合您的情况
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(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是一种将两个可能具有不同索引的DataFrame的列组合到单个结果DataFrame中的便捷方法。这是一个非常基本的示例:此处的数据对齐在索引(行标签)上。使用合并加上指示它使用索引的其他参数,可以实现相同的行为:

result = pd.merge(left, right, left_index=True, right_index=True,
how='outer')

8

区别之一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

那是正确的。如果我们在索引以外的列上合并两个数据帧,则将获得一个新索引,但如果在两个数据帧的索引上进行合并,我们将获得一个具有相同索引的数据帧。因此,为了在合并后获得相同的索引,我们可以将两个数据帧的列(我们要在其上合并)作为索引,然后将数据帧合并到新创建的索引上。
哈桑·纳耶布

非常有见地。我从不需要索引(我通常只是重置索引),但是在某些情况下这可能会有很大的不同。
艾琳

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联接,而当使用熊猫联接时,您确实希望有一个匹配的列标签以确保其联接

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.