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()