Python 在两列上合并数据帧

Python 在两列上合并数据帧,python,pandas,merge,Python,Pandas,Merge,这是来自 我有两个数据帧,如下所示: print( a ) foo bar let letval 9 foo1 bar1 let1 a 8 foo2 bar2 let1 b 7 foo3 bar3 let1 c 6 foo1 bar1 let2 z 5 foo2 bar2 let2 y 4 foo3 bar3 let2 x print( b ) foo bar n

这是来自

我有两个数据帧,如下所示:

print( a )

    foo   bar   let letval
9  foo1  bar1  let1      a
8  foo2  bar2  let1      b
7  foo3  bar3  let1      c
6  foo1  bar1  let2      z
5  foo2  bar2  let2      y
4  foo3  bar3  let2      x

print( b )

    foo   bar   num  numval
0  foo1  bar1  num1       1
1  foo2  bar2  num1       2
2  foo3  bar3  num1       3
3  foo1  bar1  num2       4
4  foo2  bar2  num2       5
5  foo3  bar3  num2       6
我想
合并
['foo','bar']
中的两个

如果我简单地执行
c=pd.merge(a,b,on=['foo','bar'])
,我会得到:

prnint( c )

     foo   bar   let letval   num  numval
0   foo1  bar1  let1      a  num1       1
1   foo1  bar1  let1      a  num2       4
2   foo1  bar1  let2      z  num1       1
3   foo1  bar1  let2      z  num2       4
4   foo2  bar2  let1      b  num1       2
5   foo2  bar2  let1      b  num2       5
6   foo2  bar2  let2      y  num1       2
7   foo2  bar2  let2      y  num2       5
8   foo3  bar3  let1      c  num1       3
9   foo3  bar3  let1      c  num2       6
10  foo3  bar3  let2      x  num1       3
11  foo3  bar3  let2      x  num2       6
我想:

print( c )

    foo   bar   let letval   num   numval
0  foo1  bar1  let1      a   num1       1
1  foo2  bar2  let1      b   num1       2
2  foo3  bar3  let1      c   num1       3
3  foo1  bar1  let2      z   num2       4
4  foo2  bar2  let2      y   num2       5
5  foo3  bar3  let2      x   num2       6
我得到的最接近的结果是:

c = pd.merge( a, b, left_index=['foo', 'bar'], right_index=['foo', 'bar'] )
我错过了什么

为什么在第一个例子中我得到
c.shape=(12,6)


编辑

多亏了这一点,我意识到根本的问题是没有一个列的组合可以做到这一点。因此,前面提出的合并问题无法单独解决。也就是说,这个问题被转化为一个更简单的问题:

如何在表之间建立单一关系?

我用一个字典解决了这个问题,它映射了需要对齐的所需输出:

map_ab = { 'num1':'let1', 'num2':'let2' }
b['let'] = b.apply( lambda x: map_ab[x['num']], axis=1 )
c = pd.merge( a, b, on=['foo', 'bar', 'let'] )
print( c )
您可以使用:


在第一个示例中,如果
bar
foo
a、b
中相等,则执行
internal join
操作,该操作将返回所有行。得到该操作的原因是,要合并的列不构成唯一的组合。例如,
a
的第一行(索引0)有
foo1
bar1
,但第四行(索引3)也有。好的,那很好,但是
b
也有同样的问题。因此,当您为索引为
0
的行匹配
b
foo1
bar1
时,它会匹配两次。当您在索引为
3
的行中匹配
foo1
bar1
时也是如此,它匹配两次。因此,这两行有四个匹配项

所以你得到了

  • a
    第0行与
    b
    第0行匹配
  • a
    第0行与
    b
    第3行匹配
  • a
    第3行与
    b
    第0行匹配
  • a
    第3行与
    b
    第3行匹配
然后,你的例子又做了两次<代码>3*4==12

要做到这一点并且不含糊,唯一的方法是决定一个规则,如果有多个匹配项,则选择哪个匹配项。我决定按你的其他专栏之一分组,然后选第一个。它仍然不符合您的预期输出,但我建议您给出一个糟糕的示例

pd.merge( a, b, on=['foo', 'bar']).groupby(['foo', 'bar', 'let'], as_index=False).first()

combine\u first
索引
上匹配。它将生成一个数据帧,该数据帧的索引为
a.index.union(b.index)
,类似于列的wise。如果您有
a=pd.DataFrame([],list('ab'),list('ab'))
b=pd.DataFrame([],list('cd'),list('cd'))
a.combine\u first(b)
将是一个4x4数据帧。关键是,您的答案忽略了这样一个事实,即OP希望在
['bar',foo']
上加入,并且实际上在给定的整数索引上匹配。是的,combine_首先起作用,因为索引匹配。如果你这样做,索引将不再起作用。另外,
merge
上的行为发生在每个连接选项(
internal
outer
,等等)上。这对发生的情况有很好的解释,特别是当您将b的foo1和bar1与索引为0的行匹配时,它会匹配两次!这个例子和我手头的问题一样好/坏。诚然,我做了一些不同的事情(导入的数据帧与文件不同),但这种情况时常发生。@Luis同意。但这就是问题所在。鉴于您提供的信息,没有一种明确的方式来提供答案。我本来可以扔下复制品的,但那不能给你想要的答案。数据或请求有问题。你需要调和并再次询问。我认为你的观点与问题不明确,我被一个事实愚弄了,我知道一个值
let1
必须对应一个值
num1
,两者毕竟都是1:P我将试着找到一个更好的例子或修改措辞以反映这一点。
pd.merge( a, b, on=['foo', 'bar']).groupby(['foo', 'bar', 'let'], as_index=False).first()