按索引合并两个数据帧

bru*_*lin 118 python merge concat dataframe pandas

嗨,我有以下数据帧:

> 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
Run Code Online (Sandbox Code Playgroud)

如何合并索引以获得:

  id begin conditional confidence discoveryTechnique   concept 
0 278    56       false        0.0                  1  A 
1 421    18       false        0.0                  1  B
Run Code Online (Sandbox Code Playgroud)

我问,因为我的理解是merge()ie 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
Run Code Online (Sandbox Code Playgroud)

合并索引是不好的做法?这不可能吗?如果是这样,我如何将索引转换为名为"index"的新列?

谢谢

jez*_*ael 237

使用merge,默认为内连接:

pd.merge(df1, df2, left_index=True, right_index=True)
Run Code Online (Sandbox Code Playgroud)

或者join,默认情况下是左连接:

df1.join(df2)
Run Code Online (Sandbox Code Playgroud)

或者concat,默认情况下是外连接:

pd.concat([df1, df2], axis=1)
Run Code Online (Sandbox Code Playgroud)

样品:

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
Run Code Online (Sandbox Code Playgroud)
#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
Run Code Online (Sandbox Code Playgroud)

  • 好的。对于阅读本文的其他人,如果它不起作用,请查看您是否需要 `.transpose()` dfs 之一来同步索引 - 那是我的问题 (4认同)
  • 非常感谢。很好的答案。但是为什么 `concat` 必须将 df 放在括号中而 `join` 和 `merge` 不需要? (2认同)

Max*_*axU 21

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

pd.concat([df1, df2, df3, ...], axis=1)
Run Code Online (Sandbox Code Playgroud)

合并以通过自定义字段/索引连接:

# 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)
Run Code Online (Sandbox Code Playgroud)

或通过索引加入加入:

 df1.join(df2)
Run Code Online (Sandbox Code Playgroud)


小智 12

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

pd.concat:
接受可迭代的参数。因此,它不能直接使用 DataFrames(使用[df,df2]
DataFrame 的维度应该沿轴匹配

Joinpd.merge:
可以采用 DataFrame 参数


小智 8

一个让我感到愚蠢的错误:连接失败,因为索引dtypes不同。这并不明显,因为两个表都是同一个原始表的数据透视表。之后reset_index,索引在Jupyter 中看起来相同。只有在保存到 Excel 时才出现...

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

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


小智 7

如果你想在 Pandas 中连接两个数据框,你可以简单地使用可用的属性,如mergeconcatenate

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

newdataframe = merge(df1, df2, left_index=True, right_index=True)
Run Code Online (Sandbox Code Playgroud)


cs9*_*s95 6

这个答案已经解决了一段时间,所有可用的选项都已经存在。但是,在此答案中,我将尝试对这些选项进行更多说明,以帮助您了解何时使用什么。

这篇文章将讨论以下主题:

  • 不同条件下与索引合并
    • 基于索引的连接选项:merge, join,concat
    • 合并索引
    • 合并索引一,其他列
  • 有效地使用命名索引来简化合并语法


基于索引的连接

TL; 博士

有几个选项,根据用例的不同,有些选项比其他选项更简单。

  1. DataFrame.mergeleft_indexright_index(或left_onright_on使用名为索引)
  2. DataFrame.join (在索引上连接)
  3. pd.concat (在索引上连接)
优点 缺点
merge

• 支持内/左/右/全
• 支持列-列、索引-列、索引-索引连接

• 一次只能加入两帧

join

• 支持inner/left(默认)/right/full
• 可以一次加入多个DataFrames

• 仅支持索引-索引连接

concat

• 擅长一次加入多个 DataFrame
• 非常快(串联是线性时间)

• 仅支持内部/完整(默认)联接
• 仅支持索引-索引联接


索引到索引连接

通常,索引内部连接如下所示:

left.merge(right, left_index=True, right_index=True)
Run Code Online (Sandbox Code Playgroud)

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

值得注意的替代品

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

     left.join(right, how='inner',)
    
    Run Code Online (Sandbox Code Playgroud)

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

  2. pd.concatjoin 索引,并且可以一次连接两个或多个 DataFrame。默认情况下,它执行完整的外部联接。

     pd.concat([left, right], axis=1, sort=False)
    
    Run Code Online (Sandbox Code Playgroud)

    有关更多信息concat,请参阅此帖子


索引到列连接

为了进行内部联接使用的右左,列的索引,你将使用DataFrame.merge的组合left_index=Trueright_on=...

left.merge(right, left_index=True, right_on='key')
Run Code Online (Sandbox Code Playgroud)

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

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


这篇文章是我在Pandas Merging 101 中工作的删节版。请点击此链接以获取有关合并的更多示例和其他主题。


Ray*_*Toh 6

您可以尝试以下几种方法来合并/加入您的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)