`pandas.merge`无法识别相同的索引

时间:2018-12-06 17:09:09

标签: python pandas dataframe

我有两个重叠的列但索引相同的数据框,我想将它们合并。我觉得这应该是直截了当的,但是我已经解决了很多例子和一些问题,但没有用,但似乎与其他例子不一致。

import pandas as pd
# create test data
df = pd.DataFrame({'gen1': [1, 0, 0, 1, 1], 'gen3': [1, 0, 0, 1, 0], 'gen4': [0, 1, 1, 0, 1]}, index = ['a', 'b', 'c', 'd', 'e'])
df1 = pd.DataFrame({'gen1': [1, 0, 0, 1, 1], 'gen2': [0, 1, 1, 1, 1], 'gen3': [1, 0, 0, 1, 0]}, index = ['a', 'b', 'c', 'd', 'e'])

In [1]: df
Out[1]: 
   gen1  gen2  gen3
a     1     0     1
b     0     1     0
c     0     1     0
d     1     1     1
e     1     1     0

In [2]: df1
Out[2]: 
   gen1  gen3  gen4
a     1     1     0
b     0     0     1
c     0     0     1
d     1     1     0
e     1     0     1

在研究完所有示例(https://pandas.pydata.org/pandas-docs/stable/merging.html)之后,我相信我已经找到了正确的示例(合并的第一个和第二个示例)。第二个示例是这样:

In [43]: result = pd.merge(left, right, on=['key1', 'key2'])

在他们的示例中,他们有两个DF(左和右),它们具有重叠的列和相同的索引,并且它们产生的数据帧具有每一列的一个版本和原始索引,但是当我这样做时,不会发生这种情况:

# get the intersection of columns (I need this to be general)
In [3]: column_intersection = list(set(df).intersection(set(df1))

In [4]: pd.merge(df, df1, on=column_intersection)
Out[4]: 
   gen1  gen2  gen3  gen4
0     1     0     1     0
1     1     0     1     0
2     1     1     1     0
3     1     1     1     0
4     0     1     0     1
5     0     1     0     1
6     0     1     0     1
7     0     1     0     1
8     1     1     0     1

在这里,我们看到合并还没有看到索引相同!我摆弄了各种选项,但无法获得想要的结果。

这里How to keep index when using pandas merge提出了一个类似但又不同的问题,但我不太了解答案,因此无法将其与我的问题联系起来。

此特定示例的要点:

  • 索引将始终相同。
  • 具有相同名称的列将始终具有相同的条目(即,它们是重复的)。

有一个解决这个特定问题的方法很棒,但是我也很想理解它,因为我发现自己不时花费大量时间来合并数据帧。我喜欢熊猫,总的来说,我觉得它非常直观,但是除了琐碎的数据框组合之外,我似乎对其他任何东西都不满意。

2 个答案:

答案 0 :(得分:3)

从v0.23开始,可以为连接键指定索引名称(如果有)。

df.index.name = df1.index.name = 'idx'
df.merge(df1, on=list(set(df).intersection(set(df1)) | {'idx'}))

     gen1  gen3  gen4  gen2
idx                        
a       1     1     0     0
b       0     0     1     1
c       0     0     1     1
d       1     1     0     1
e       1     0     1     1 

这里的假设是,您实际的DataFrame在重叠的列中没有完全相同的值。如果他们这样做了,那么您的问题将是串联的之一—您可以为此使用pd.concat

c = list(set(df).intersection(set(df1)))
pd.concat([df1, df.drop(c, 1)], axis=1)

     gen1  gen2  gen3  gen4                     
a       1     0     1     0
b       0     1     0     1
c       0     1     0     1
d       1     1     1     0
e       1     1     0     1

答案 1 :(得分:2)

在这种特殊情况下,您可以使用assign
df中的内容优先,但df1中的所有其他内容均包含在内。

df1.assign(**df)

   gen1  gen2  gen3  gen4
a     1     0     1     0
b     0     1     0     1
c     0     1     0     1
d     1     1     1     0
e     1     1     0     1

**df假定字典上下文解压缩df。这种解压缩将关键字参数传递给assign,其中以列名作为关键字,以列名作为参数。

相同
df1.assign(gen1=df.gen1, gen3=df.gen3, gen4=df.gen4)