我真的很难理解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]})
现在,当我运行以下命令时:
pd.merge(left, right, left_on=['key2', 'key1'], right_on=['key1', 'key2'], how='outer', indicator=True, left_index=True)
我得到:
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
但是,与right_index=True
一起运行会产生错误。如果我都介绍的话也一样。更有趣的是,运行以下合并会产生非常意外的结果
pd.merge(left, right, on=['key1', 'key2'],how='outer', validate = 'one_to_many', indicator=True, left_index = True, right_index = True)
结果是:
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
如您所见,key1
和key2
右框的所有信息都完全丢失。
请帮助我理解这些论点的目的和功能。谢谢。
答案 0 :(得分:2)
列-列合并:使用left_on,right_on以及如何使用。
示例:
# 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)
索引-索引合并::将left_index和right_index设置为True或使用on并使用方式。
示例:
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
列索引合并:使用left_on + right_index或left_index + right_on以及如何使用。
注意:index和left_on中的值必须匹配。如果索引是整数,而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)
您有点混淆了不同类型的合并,从而产生了奇怪的结果。 如果您从概念上看不到合并的方式,则很可能计算机无法做得更好。
答案 1 :(得分:1)
如果我正确理解merge
的行为,则应该分别为left
和right
选择一个选项(即您不应该选择{{ 1}}和left_on=['x']
同时)。否则,可能会以任意方式发生奇怪的事情,因为它使left_index=True
混淆了应实际使用哪个merge
,正如您在key
的当前实现中所显示的那样(我没有检查过pandas源详细信息,但行为可能会因每个版本中的不同实现而发生变化)。这是一个小实验。
merge
(1)>>> 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
使用merge
['key1', 'key2']
(2)将>>> 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
设置为['key1', 'key2']
索引,并使用索引和键将其left
设置
merge
(3)进一步将>>> 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
设置为['key1', 'key2']
索引,并使用索引right
merge
请注意,上面的(1)(2)(3)显示的结果相同,即使将>>> 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
设置为索引,您仍然可以使用['key1', 'key2']
代替{{1} }。
现在,如果您真的想同时使用left_on = ['key1', 'key2']
和left_index=True
合并,实现此目的的一种方法是:
['key1', 'key2']
如果您读到这里,我现在很确定您知道如何使用多种不同的方法来实现上述目标。 希望这会有所帮助。