按索引合并两个数据帧

Merge two dataframes by index

我有以下数据框:

> df1
  id begin conditional confidence discoveryTechnique  
0 278    56       false        0.0                  1   
1 421    18       false        0.0                  1 

> df2
   concept 
0  A  
1  B
   

如何合并索引以获得:

  id begin conditional confidence discoveryTechnique   concept 
0 278    56       false        0.0                  1  A 
1 421    18       false        0.0                  1  B

我问是因为我的理解是 merge()df1.merge(df2) 使用列来进行匹配。事实上,这样做我得到:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/pandas/core/frame.py", line 4618, in merge
    copy=copy, indicator=indicator)
  File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 58, in merge
    copy=copy, indicator=indicator)
  File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 491, in __init__
    self._validate_specification()
  File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 812, in _validate_specification
    raise MergeError('No common columns to perform merge on')
pandas.tools.merge.MergeError: No common columns to perform merge on

在索引上合并是不好的做法吗?不可能吗?如果是这样,我怎样才能将索引移动到名为“index”的新列中?

使用merge,默认是内连接:

pd.merge(df1, df2, left_index=True, right_index=True)

join,默认为左连接:

df1.join(df2)

concat),默认为外连接:

pd.concat([df1, df2], axis=1)

示例:

df1 = pd.DataFrame({'a':range(6),
                    'b':[5,3,6,9,2,4]}, index=list('abcdef'))

print (df1)
   a  b
a  0  5
b  1  3
c  2  6
d  3  9
e  4  2
f  5  4

df2 = pd.DataFrame({'c':range(4),
                    'd':[10,20,30, 40]}, index=list('abhi'))

print (df2)
   c   d
a  0  10
b  1  20
h  2  30
i  3  40

# Default inner join
df3 = pd.merge(df1, df2, left_index=True, right_index=True)
print (df3)
   a  b  c   d
a  0  5  0  10
b  1  3  1  20

# Default left join
df4 = df1.join(df2)
print (df4)
   a  b    c     d
a  0  5  0.0  10.0
b  1  3  1.0  20.0
c  2  6  NaN   NaN
d  3  9  NaN   NaN
e  4  2  NaN   NaN
f  5  4  NaN   NaN

# Default outer join
df5 = pd.concat([df1, df2], axis=1)
print (df5)
     a    b    c     d
a  0.0  5.0  0.0  10.0
b  1.0  3.0  1.0  20.0
c  2.0  6.0  NaN   NaN
d  3.0  9.0  NaN   NaN
e  4.0  2.0  NaN   NaN
f  5.0  4.0  NaN   NaN
h  NaN  NaN  2.0  30.0
i  NaN  NaN  3.0  40.0

您可以使用 concat([df1, df2, ...], axis=1) 连接两个或多个按索引对齐的 DF:

pd.concat([df1, df2, df3, ...], axis=1)

merge 用于按自定义字段/索引连接:

# join by _common_ columns: `col1`, `col3`
pd.merge(df1, df2, on=['col1','col3'])

# join by: `df1.col1 == df2.index`
pd.merge(df1, df2, left_on='col1' right_index=True)

join按索引加入:

 df1.join(df2)

如果您想在 Pandas 中加入两个数据框,您可以简单地使用可用的属性,例如 mergeconcatenate

例如,如果我有两个数据框 df1df2,我可以通过以下方式加入它们:

newdataframe = merge(df1, df2, left_index=True, right_index=True)

一个愚蠢的 bug 惹恼了我:连接失败,因为索引 dtypes 不同。这并不明显,因为两个 table 都是同一个原始 table 的枢轴 table。在 reset_index 之后,索引在 Jupyter 中看起来完全相同。它只在保存到 Excel...

时才被发现

我修复了它:df1[['key']] = df1[['key']].apply(pd.to_numeric)

希望这能为某人节省一个小时!

默认:
join 是按列左连接
pd.merge 是按列的内连接
pd.concat 是按行外连接

pd.concat:
采用 Iterable 参数。因此,它不能直接获取数据帧(使用[df,df2]
DataFrame 的尺寸应沿轴

匹配

Joinpd.merge:
可以接受 DataFrame 参数

This answer has been resolved for a while and all the available options are already out there. However in this answer I'll attempt to shed a bit more light on these options to help you understand when to use what.

本 post 将讨论以下主题:

  • 在不同条件下与索引合并
    • 基于索引的连接选项:mergejoinconcat
    • 合并索引
    • 合并一个的索引,另一个的列
  • 有效地使用命名索引来简化合并语法


基于索引的连接

TL;DR

There are a few options, some simpler than others depending on the use case.

  1. DataFrame.merge with left_index and right_index (or left_on and right_on using named indexes)
  2. DataFrame.join (joins on index)
  3. pd.concat (joins on index)
PROS CONS
merge

• supports inner/left/right/full
• supports column-column, index-column, index-index joins

• can only join two frames at a time

join

• supports inner/left (default)/right/full
• can join multiple DataFrames at a time

• only supports index-index joins

concat

• specializes in joining multiple DataFrames at a time
• very fast (concatenation is linear time)

• only supports inner/full (default) joins
• only supports index-index joins


索引到索引连接

通常,索引 上的内部联接看起来像这样:

left.merge(right, left_index=True, right_index=True)

其他类型的联接(左、右、外)遵循类似的语法(并且可以使用 how=... 进行控制)。

值得注意的替代品

  1. DataFrame.join 默认为索引上的左外连接。

     left.join(right, how='inner',)
    

    如果您碰巧得到 ValueError: columns overlap but no suffix specified,您将需要指定 lsuffixrsuffix= 参数来解决这个问题。由于列名相同,因此需要区分后缀。

  2. pd.concat 加入索引,可以同时加入两个或多个 DataFrame。它默认执行完全外部连接。

     pd.concat([left, right], axis=1, sort=False)
    

    有关 concat 的详细信息,请参阅


列连接的索引

要使用左索引、右列执行内部联接,您将使用 DataFrame.merge left_index=Trueright_on=... 的组合。

left.merge(right, left_index=True, right_on='key')

其他联接遵循类似的结构。注意 只有 merge 可以执行索引到列的连接。您可以连接多个 levels/columns,前提是左侧的索引级别数等于右侧的列数。

joinconcat 不能进行混合合并。您需要使用 DataFrame.set_index.

将索引设置为前置步骤

此 post 是我在 中的工作的删节版。请关注此 link 以获得更多示例和其他有关合并的主题。

您可以尝试以下几种方法来 merge/join 您的 dataframe

  1. merge(默认内连接)

    df = pd.merge(df1, df2, left_index=True, right_index=True)

  2. join(默认左连接)

    df = df1.join(df2)

  3. concat(默认外连接)

    df = pd.concat([df1, df2], axis=1)