一个常见的 pandas merge 两张表的场景如下:
我们准备在 [key1, key2] 上 merge 表 a 和表 b
表 a
idx key1 key2
0 1 1 1
1 2 3 2
2 3 4 4
3 5 5 5
4 7 6 7
表 b
id key2 key1
0 1 1 1
1 2 2 3
2 3 4 4
3 5 5 5
4 7 7 6
虽然二者的 key2 key1 的顺序不同,但是在普通 merge,指定on=['key1', 'key2']
或者on=['key2', 'key1']
都可以,会分别匹配两个键
a.merge(b, on=['key1', 'key2'], how='left')
idx key1 key2 id
0 1 1 1 1
1 2 3 2 2
2 3 4 4 3
3 5 5 5 5
4 7 6 7 7
a.merge(b, on=['key2', 'key1'], how='left')
idx key1 key2 id
0 1 1 1 1
1 2 3 2 2
2 3 4 4 3
3 5 5 5 5
4 7 6 7 7
但是如果我们用另一种方式 merge,left
指定列名,而right
使用index
b = b.set_index(['key2', 'key1'])
a.merge(b, left_on=['key1', 'key2'], right_index=True, how='left')
idx key1 key2 id
0 1 1 1 1.0
1 2 3 2 NaN
2 3 4 4 3.0
3 5 5 5 5.0
4 7 6 7 NaN
可以看到left
表提供的是按照left_on
顺序给出的键值,而right
表是按照index
顺序给出的键值,导致出现了没有匹配的情况
而如果更换一下left_on
顺序:
a.merge(b, left_on=['key2', 'key1'], right_index=True, how='left')
idx key1 key2 id
0 1 1 1 1
1 2 3 2 2
2 3 4 4 3
3 5 5 5 5
4 7 6 7 7
可以发现匹配就成功了
这应该是因为当使用index
进行匹配的时候,索引往往是用tuple
存储的,作为不可变类型,元素的顺序也不能改变,可能压根就不会去匹配元组的元素名称和列表的元素名称,而列表表示键值顺序的left
表,就会根据每个元素的名称去DataFrame
中找到对应的列名