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

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)

正如你所看到的,所有的信息,右侧框架key1key2完全丧失。

请帮助我理解这些参数的目的和功能。谢谢你。

Tam*_* Le 7

合并有两种方式:

列列合并:使用 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)

你有点混淆了不同类型的合并,这会产生奇怪的结果。如果您无法从概念上看出合并将如何发生,那么计算机很可能不会做得更好。


gyo*_*oza 7

如果我正确理解 的行为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)

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