ste*_*kwr 8 python merge join pandas
我真的很难理解 pandas.merge 中的“left_index”和“right_index”参数。我阅读了文档,四处搜索,尝试了各种设置并试图理解,但我仍然感到困惑。考虑这个例子:
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
'key2': ['K0', 'K1', 'K0', 'K1'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
'key2': ['K0', 'K0', 'K0', 'K0'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3'],
'E': [1,2,3,4]})
Run Code Online (Sandbox Code Playgroud)
现在,当我运行以下命令时:
pd.merge(left, right, left_on=['key2', 'key1'], right_on=['key1', 'key2'], how='outer', indicator=True, left_index=True)
Run Code Online (Sandbox Code Playgroud)
我得到:
key1_x key2_x A B key1_y key2_y C D E _merge
0 K0 K0 A0 B0 K0 K0 C0 D0 1.0 both
1 K0 K1 A1 B1 K1 K0 C1 D1 2.0 both
2 K0 K1 A1 B1 K1 K0 C2 D2 3.0 both
3 K1 K0 A2 B2 NaN NaN NaN NaN NaN left_only
3 K2 K1 A3 B3 NaN NaN NaN NaN NaN left_only
3 NaN NaN NaN NaN K2 K0 C3 D3 4.0 right_only
Run Code Online (Sandbox Code Playgroud)
但是,运行相同的 withright_index=True会出错。如果我同时介绍两者,则相同。更有趣的是,运行以下合并给出了一个非常意想不到的结果
pd.merge(left, right, on=['key1', 'key2'],how='outer', validate = 'one_to_many', indicator=True, left_index = True, right_index = True)
Run Code Online (Sandbox Code Playgroud)
结果是:
key1 key2 A B C D E _merge
0 K0 K0 A0 B0 C0 D0 1 both
1 K0 K1 A1 B1 C1 D1 2 both
2 K1 K0 A2 B2 C2 D2 3 both
3 K2 K1 A3 B3 C3 D3 4 both
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,所有的信息,右侧框架key1和key2完全丧失。
请帮助我理解这些参数的目的和功能。谢谢你。
列列合并:使用 left_on、right_on 和 how。
例子:
# Gives same answer
pd.merge(left, right, left_on=['key2', 'key1'], right_on=['key1', 'key2'], how = 'outer')
pd.merge(left, right, on=['key1', 'key2'], how='outer', indicator=True)
Run Code Online (Sandbox Code Playgroud)
索引索引合并:将 left_index 和 right_index 设置为 True 或使用 on 并使用 how。
例子:
pd.merge(left, right, how = 'inner', right_index = True, left_index = True)
# If you make matching unique multi-indexes for both data frames you can do
# pd.merge(left, right, how = 'inner', on = ['indexname1', 'indexname2'])
# In your data frames, you're keys duplicate values so you can't do this
# In general, a column with duplicate values does not make a good key
Run Code Online (Sandbox Code Playgroud)
列索引合并:使用 left_on + right_index 或 left_index + right_on 以及如何使用。
注意: index 和 left_on 中的值都必须匹配。如果你的 index 是一个整数而你的 left_on 是一个字符串,你会得到错误。此外,索引级别的数量必须匹配。
例子:
# If how not specified, inner join is used
pd.merge(left, right, right_on=['E'], left_index = True, how = 'outer')
# Gives error because left_on is string and right_index is integer
pd.merge(left, right, left_on=['key1'], right_index = True, how = 'outer')
# This gave you error because left_on has indexing level of 2 but right_index only has indexing level of 1.
pd.merge(left, right, left_on=['key2', 'key1'], right_on=['key1', 'key2'], how='outer', indicator=True, right_index=True)
Run Code Online (Sandbox Code Playgroud)
你有点混淆了不同类型的合并,这会产生奇怪的结果。如果您无法从概念上看出合并将如何发生,那么计算机很可能不会做得更好。
如果我正确理解 的行为merge,您应该分别只选择left和的一个选项right(即您不应该同时选择left_on=['x']和)。left_index=True否则,奇怪的事情可能会以任意方式发生,因为它会混淆应该实际使用merge哪个,key正如您在当前实现中所示的那样merge(我没有详细检查 pandas 源代码,但每个版本中的不同实现的行为可能会发生变化) 。这是一个小实验。
>>> left
key1 key2 A B
0 K0 K0 A0 B0
1 K0 K1 A1 B1
2 K1 K0 A2 B2
3 K2 K1 A3 B3
>>> right
key1 key2 C D E
0 K0 K0 C0 D0 1
1 K1 K0 C1 D1 2
2 K1 K0 C2 D2 3
3 K2 K0 C3 D3 4
Run Code Online (Sandbox Code Playgroud)
(1)merge使用['key1', 'key2']
>>> pd.merge(left, right, on=['key1', 'key2'], how='outer')
key1 key2 A B C D E
0 K0 K0 A0 B0 C0 D0 1.0
1 K0 K1 A1 B1 NaN NaN NaN
2 K1 K0 A2 B2 C1 D1 2.0
3 K1 K0 A2 B2 C2 D2 3.0
4 K2 K1 A3 B3 NaN NaN NaN
5 K2 K0 NaN NaN C3 D3 4.0
Run Code Online (Sandbox Code Playgroud)
(2) 设置['key1', 'key2']为left索引并merge使用索引和键
>>> left = left.set_index(['key1', 'key2'])
>>> pd.merge(left, right, left_index=True, right_on=['key1', 'key2'], how='outer').reset_index(drop=True)
A B key1 key2 C D E
0 A0 B0 K0 K0 C0 D0 1.0
1 A1 B1 K0 K1 NaN NaN NaN
2 A2 B2 K1 K0 C1 D1 2.0
3 A2 B2 K1 K0 C2 D2 3.0
4 A3 B3 K2 K1 NaN NaN NaN
5 NaN NaN K2 K0 C3 D3 4.0
Run Code Online (Sandbox Code Playgroud)
(3)进一步设置['key1', 'key2']为right索引并merge使用该索引
>>> right = right.set_index(['key1', 'key2'])
>>> pd.merge(left, right, left_index=True, right_index=True, how='outer').reset_index()
key1 key2 A B C D E
0 K0 K0 A0 B0 C0 D0 1.0
1 K0 K1 A1 B1 NaN NaN NaN
2 K1 K0 A2 B2 C1 D1 2.0
3 K1 K0 A2 B2 C2 D2 3.0
4 K2 K0 NaN NaN C3 D3 4.0
5 K2 K1 A3 B3 NaN NaN NaN
Run Code Online (Sandbox Code Playgroud)
请注意,上面的 (1)(2)(3) 显示了相同的结果,即使['key1', 'key2']设置为索引,您仍然可以left_on = ['key1', 'key2']使用left_index=True。
现在,如果您确实想使用两者进行合并['key1', 'key2'],index实现此目的的一种方法是:
>>> pd.merge(left.reset_index(), right.reset_index(), on=['index', 'key1', 'key2'], how='outer')
index key1 key2 A B C D E
0 0 K0 K0 A0 B0 C0 D0 1.0
1 1 K0 K1 A1 B1 NaN NaN NaN
2 2 K1 K0 A2 B2 C2 D2 3.0
3 3 K2 K1 A3 B3 NaN NaN NaN
4 1 K1 K0 NaN NaN C1 D1 2.0
5 3 K2 K0 NaN NaN C3 D3 4.0
Run Code Online (Sandbox Code Playgroud)
如果您读到这里,我很确定您现在知道如何使用多种不同的方式实现上述目标。希望这可以帮助。