这是this question的后续
我有两个数据帧,如下所示:
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
我想merge
列[ '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)
?你知道吗
编辑
多亏了@piRSquared's answer,我意识到根本的问题是没有一个列的组合可以做到这一点。因此,前面提出的合并问题不能一元化地解决。也就是说,这个问题转化为一个更简单的问题:
如何在表之间建立统一的关系?
我用一个字典解决了这个问题,它映射了需要对齐的所需的输出:
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 )
之所以会出现这种情况,是因为要合并的列不构成唯一的组合。例如,
a
的第一行(索引0)有foo1
和bar1
,但第四行(索引3)也有。好吧,那很好,但是b
也有同样的问题。因此,当您将b
的foo1
&;bar1
与0
索引的行匹配时,它会匹配两次。当您匹配foo1
&;在索引为3
的行中的bar1
时也是如此,它匹配两次。所以这两行有四个匹配项。你知道吗所以你得到
a
行0与b
行0匹配a
行0与b
行3匹配a
行3与b
行0匹配a
行3与b
行3匹配然后,你的例子又做了两次。
3 * 4 == 12
唯一能做到这一点并且毫不含糊的方法是决定一个规则,如果有多个匹配项,那么就选择哪个匹配项。我决定按你的其他专栏之一分组,然后选第一个专栏。它仍然不符合你的预期输出,但我建议你给出一个坏的例子。你知道吗
您可以使用combine_first:
在第一个示例中,您正在执行
inner join
,如果bar
&;foo
在a,b
中相等,则返回所有行。你知道吗相关问题 更多 >
编程相关推荐