如果左右df的键不同,pandas merge会做奇怪的工作

时间:2017-03-15 02:26:20

标签: python pandas join merge

如果左右键的索引不同,我发现pandas merge方法做得很奇怪。

例如,我将左右数据帧定义如下

left_df

   0  1  2  3  4  5
0  1  2  1  2  3  4
1  2  3  2  3  4  5
2  1  2  3  4  5  6
3  2  2  4  5  6  7
4  2  3  5  6  7  8

right_df

   0  1  2  3  4  5
0  1  2  3  4  5  6
1  1  2  3  4  5  7
2  2  3  4  5  6  7
3  2  3  4  5  6  8

并使用一些参数合并作业

pd.merge(left_df, right_df, how="inner", left_on = [0,1], right_on=[0,1], indicator=False)

结果如预期那样找到。

       0  1  2_x  3_x  4_x  5_x  2_y  3_y  4_y  5_y
    0  1  2    1    2    3    4    3    4    5    6
    1  1  2    1    2    3    4    3    4    5    7
    2  1  2    3    4    5    6    3    4    5    6
    3  1  2    3    4    5    6    3    4    5    7
    4  2  3    2    3    4    5    4    5    6    7
    5  2  3    2    3    4    5    4    5    6    8
    6  2  3    5    6    7    8    4    5    6    7
    7  2  3    5    6    7    8    4    5    6    8

但如果我将left_on和right_on params设置为不同,结果会变得非常奇怪,如下所示。

merge job with '1,2' left key index

pd.merge(left_df, right_df, how="inner", left_on = [1,2], right_on=[0,1], indicator=False)


   1  2  0_x  1_x  2_x  3_x  4_x  5_x  0_y  1_y  2_y  3_y  4_y  5_y
0  2  3    1    2    3    4    5    6    2    3    4    5    6    7
1  2  3    1    2    3    4    5    6    2    3    4    5    6    8

                ^    ^                   ^    ^
                 these columns are duplicated.

   0_x    1    2  3_x  4_x  5_x  2_y  3_y  4_y  5_y
0    1    2    3    4    5    6    4    5    6    7
1    1    2    3    4    5    6    4    5    6    8
this is what I expected. (keys of each df are removed.)

是否有任何参数或方法可以解决上述奇怪的工作?

1 个答案:

答案 0 :(得分:0)

我想知道我提到的奇怪结果的情况,所以我将自己的假设分为两种情况。

  • 每个键的列名不同
  • 每个键的列索引(在本例中,数据框中的绝对列位置。)不同

通过一些测试用例,我可以找出当每个键的列名不同时,结果不太好。

所以这个问题可以很容易地处理chaning columns name。

left_df
   0  key0  key1  3  4  5
0  1     2     1  2  3  4
1  2     3     2  3  4  5
2  1     2     3  4  5  6
3  2     2     4  5  6  7
4  2     3     5  6  7  8

right_df
   key0  key1  2  3  4  5
0     1     2  3  4  5  6
1     1     2  3  4  5  7
2     2     3  4  5  6  7
3     2     3  4  5  6  8

result
   0  key0  key1  3_x  4_x  5_x  2  3_y  4_y  5_y
0  1     2     3    4    5    6  4    5    6    7
1  1     2     3    4    5    6  4    5    6    8

以下是简单的代码实现。

        key_entry = []
        for i in range(len([1,2])):
            key_entry.append('key' + str(i))

        left_rename_map = {}
        for i, each in zip([1,2], key_entry):
            left_rename_map[i] = each

        right_rename_map = {}
        for i, each in zip([0,1], key_entry):
            right_rename_map[i] = each

        df1 = df1.rename(columns=left_rename_map)
        df2 = df2.rename(columns=right_rename_map)

在我看来,Pandas会尝试保存所有列信息(在本例中为列名)。因此,如果键的列名不同,Pandas认为该列不相同,并且虽然每个值都与列相同,但它不会删除键列。