了解熊猫合并中的“ left_index”和“ right_index”参数

时间:2018-08-13 02:52:29

标签: python pandas join merge

我真的很难理解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

如您所见,key1key2右框的所有信息都完全丢失。

请帮助我理解这些论点的目的和功能。谢谢。

2 个答案:

答案 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的行为,则应该分别为leftright选择一个选项(即您不应该选择{{ 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']

如果您读到这里,我现在很确定您知道如何使用多种不同的方法来实现上述目标。 希望这会有所帮助。