【问题标题】:Merge two dataframes by index按索引合并两个数据框
【发布时间】:2017-03-20 23:12:40
【问题描述】:

我有以下数据框:

> 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

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

【问题讨论】:

  • 试试这个:df1.join(df2)
  • 如果你想通过一个数据框的索引和第二个数据框的一列来连接怎么办。 (我的第二个数据框有一列与第一个 df 中的索引匹配。)

标签: python pandas dataframe merge concat


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

        您可以使用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)
        

        【讨论】:

          【解决方案5】:

          使用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
          

          【讨论】:

          • 不错。对于阅读本文的其他人,如果它不起作用,请查看您是否需要 .transpose() 您的一个 dfs 来同步索引 - 这是我的问题
          • 非常感谢。很好的答案。但是为什么concat 必须把df 放在括号中,而joinmerge 不用呢?
          • @Bowen Liu 在我看来,可能在dfs = [df1, df2, df3,... dfn]df = pd. concat(dfs) 等列表中连接多个DataFrames
          【解决方案6】:

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

          这篇文章将涉及以下主题:

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


          基于索引的联接

          TL;DR

          有几个选项,根据用途,有些比其他更简单 案例。

          1. DataFrame.mergeleft_indexright_index(或 left_onright_on 使用命名索引)
          2. DataFrame.join(加入索引)
          3. pd.concat(加入索引)
          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


          索引到索引连接

          通常,inner join on index 如下所示:

          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 的更多信息,请参阅this post


          索引到列连接

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

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

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

          joinconcat 不能混合合并。您需要使用DataFrame.set_index 将索引设置为前置步骤。


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

          【讨论】:

            【解决方案7】:

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

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

            Joinpd.merge:
            可以接受 DataFrame 参数

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-10-28
              • 2018-10-30
              • 2012-03-21
              • 2021-09-19
              相关资源
              最近更新 更多