python - 合并 Pandas 中的公共(public)列值会产生不正确的数据框

标签 python pandas merge

<分区>

我正在尝试基于公共(public)列合并 pandas 中的 2 个数据框。阅读有关合并的文档,我所做的一切都暗示数据框应该合并到指定的列上,同时只保留公共(public)值。它当然保留了共同的值(value),但产生了一个巨大的数据帧,对于“左”数据帧中的每个索引,它本质上是一个完整的“右”数据帧。

我的左边数据框是

left
Out[325]: 
     A   B   C   D MergeThis
0   38  43  20  34       -N2
1   14  44  23  91       -N2
2   55  50  30  92       -N2
3   29  20  56   0       -N2
4   61   6  38  44       -N2
5   18  61  30   7       -N2
6   67  45  60  81       -N2
7    7  53  60  72       +N2
8   15  46   0  82       +N2
9    6  90  83  36       +N2
10   0  87  64  82       +N2
11  13  22  13  39       +N2
12  65  88  50  34       +N2
13  35  31  72  34       +N2

我正确的数据框是

right
Out[326]: 
    E   F   G   H MergeThis
0  22  81  97  28       +N2
1  20   4  44  48       +N2
2  19  41  52  25       +N2
3  30  37  66  24       +N2
4  32  40  56  92       +N2
5  95  76  91  31       +N2
6  36  66  17  85       +N2

显然,我试图在“MergeThis”列上进行合并,这样我最终得到 +N2 值的组合,以及来自“左”和“右”的列。然而,我最终得到的是一些奇怪的东西:

left.merge(right, on='MergeThis')
Out[327]: 
     A   B   C   D MergeThis   E   F   G   H
0    7  53  60  72       +N2  22  81  97  28
1    7  53  60  72       +N2  20   4  44  48
2    7  53  60  72       +N2  19  41  52  25
3    7  53  60  72       +N2  30  37  66  24
4    7  53  60  72       +N2  32  40  56  92
5    7  53  60  72       +N2  95  76  91  31
6    7  53  60  72       +N2  36  66  17  85
7   15  46   0  82       +N2  22  81  97  28
8   15  46   0  82       +N2  20   4  44  48
9   15  46   0  82       +N2  19  41  52  25
10  15  46   0  82       +N2  30  37  66  24
11  15  46   0  82       +N2  32  40  56  92
12  15  46   0  82       +N2  95  76  91  31
13  15  46   0  82       +N2  36  66  17  85
14   6  90  83  36       +N2  22  81  97  28
15   6  90  83  36       +N2  20   4  44  48
16   6  90  83  36       +N2  19  41  52  25
17   6  90  83  36       +N2  30  37  66  24
18   6  90  83  36       +N2  32  40  56  92
19   6  90  83  36       +N2  95  76  91  31
20   6  90  83  36       +N2  36  66  17  85
21   0  87  64  82       +N2  22  81  97  28
22   0  87  64  82       +N2  20   4  44  48
23   0  87  64  82       +N2  19  41  52  25
24   0  87  64  82       +N2  30  37  66  24
25   0  87  64  82       +N2  32  40  56  92
26   0  87  64  82       +N2  95  76  91  31
27   0  87  64  82       +N2  36  66  17  85
28  13  22  13  39       +N2  22  81  97  28
29  13  22  13  39       +N2  20   4  44  48
30  13  22  13  39       +N2  19  41  52  25
31  13  22  13  39       +N2  30  37  66  24
32  13  22  13  39       +N2  32  40  56  92
33  13  22  13  39       +N2  95  76  91  31
34  13  22  13  39       +N2  36  66  17  85
35  65  88  50  34       +N2  22  81  97  28
36  65  88  50  34       +N2  20   4  44  48
37  65  88  50  34       +N2  19  41  52  25
38  65  88  50  34       +N2  30  37  66  24
39  65  88  50  34       +N2  32  40  56  92
40  65  88  50  34       +N2  95  76  91  31
41  65  88  50  34       +N2  36  66  17  85
42  35  31  72  34       +N2  22  81  97  28
43  35  31  72  34       +N2  20   4  44  48
44  35  31  72  34       +N2  19  41  52  25
45  35  31  72  34       +N2  30  37  66  24
46  35  31  72  34       +N2  32  40  56  92
47  35  31  72  34       +N2  95  76  91  31
48  35  31  72  34       +N2  36  66  17  85

这基本上为我的“正确”数据框的每个索引创建了一个重复的数据框。

一方面,我知道如何做另一种解决方法来使用更多代码获取我想要的数据框,并进一步分解其中一个数据框,以便合并“更漂亮”。但是,我真的很想知道为什么会这样?我希望将来能够使用合并功能,但我不完全理解 pandas 正在尝试做什么来产生这个功能。

非常感谢任何帮助。

最佳答案

结果看起来是正确的。连接条件是 left 的每一行 MergeThis 等于 +N2 连接到 right 的每一行> 具有该匹配条件。每个数据帧中有 7 个这样的行,导致输出中行集的笛卡尔积有 49 行。

请注意,DataFrame.merge 的合并类型是leftrightinner outer,它确定用于连接的键集,而不是限制哪些行将与哪些其他行匹配。 inner 的默认值只是意味着使用 leftright 之间的连接列中包含的值的交集,这将只是+N2 无论如何。如果您使用 right,您会得到相同的结果,因为 right DataFrame 仅包含此列的 +N2。同样,如果您使用 leftouter 在这种情况下,它们恰好彼此相同,因为任何一个都会导致可能的匹配集基于 -N2+N2 并且您将从 +N2 的所有成对匹配中获得 49 行加上 -N2 的其他行(但没有额外的匹配项,在这种情况下,NaN 列的值来自 right)。

从它的声音来看,您可能期望 right 中的 7 行 +N2 只是附加到 leftNaN 填充其他行。为此,您应该使用连接而不是基于合并的连接。

这是一个使用 pandas.concat 的类似玩具数据的示例(您可以在完成后删除额外的 MergeThis 列),

In [42]: right
Out[42]:
   C  D MergeThis
0  1  2       +N2
1  3  4       +N2
2  5  6       +N2
3  7  8       +N2

In [43]: left
Out[43]:
    A   B MergeThis
0   1   2       -N2
1   3   4       -N2
2   5   6       +N2
3   7   8       +N2
4   9  10       +N2
5  11  12       +N2

In [44]: right.index = left[left.MergeThis == '+N2'].index.values

In [45]: right
Out[45]:
   C  D MergeThis
2  1  2       +N2
3  3  4       +N2
4  5  6       +N2
5  7  8       +N2

In [46]: pandas.concat([left, right], axis=1)
Out[46]:
    A   B MergeThis    C    D MergeThis
0   1   2       -N2  NaN  NaN       NaN
1   3   4       -N2  NaN  NaN       NaN
2   5   6       +N2  1.0  2.0       +N2
3   7   8       +N2  3.0  4.0       +N2
4   9  10       +N2  5.0  6.0       +N2
5  11  12       +N2  7.0  8.0       +N2

关于python - 合并 Pandas 中的公共(public)列值会产生不正确的数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53658207/

相关文章:

python - 排序可以连接形成多边形的打乱点(在 python 中)

python - 加载 txt 文件时跳过行

python - 将多个返回值附加到 Python 中的不同列表

python - 仅保留具有逗号分隔列表的数据框单元格中两个连字符之间的字符

python - Pandas:更新第二个数据帧的列值

winforms - 有没有更简单的方法来 merge Windows 窗体 .Designer 文件?

arrays - Pascal 的合并排序示例

qlabel 中的 python 错误 : can not show . gif

python - 删除行值类似于 '[ ]' 的数据框列

version-control - 确保分支之间的 merge 发生在一个方向