熊猫多索引数据框合并问题

Posted

技术标签:

【中文标题】熊猫多索引数据框合并问题【英文标题】:Pandas multi-index dataframe merge issue 【发布时间】:2021-03-25 07:57:35 【问题描述】:

我想合并两个具有多索引列的数据框 df1 和 df2:

mi1 = pd.MultiIndex.from_tuples([('id', '0'), ('car', '2018')], names=['variable', 'year'])
mi2 = pd.MultiIndex.from_tuples([('id', '0'), ('car', '2019')], names=['variable', 'year'])
df1 = pd.DataFrame([['alice', 1], ['bob', 2]], columns=mi1)
df2 = pd.DataFrame([['alice', 2], ['bob', 3]], columns=mi2)

在 df1 和 df2 中,第一列索引指的是变量名,而第二列索引指的是年份。一些变量,如本例中的“id”,与特定年份无关,因此为“0”值,在这里没有发生。

df1
variable     id  car
year          0 2018
0         alice    1
1           bob    2

df2
variable     id  car
year          0 2019
0         alice    2
1           bob    3

我想合并 df1 和 df2 得到:

variable     id  car  car
year          0 2018 2029
0         alice    1    2
1           bob    2    3

问题是使用 'id' 列的合并函数,应用于 df1 和 df2,返回错误消息:

df3 = pd.merge(df1, df2, on=('id', '0'), how="outer")

Traceback (most recent call last):
  File "<input>", line 5, in <module>
  File "C:\Users\AA\AppData\Roaming\Python\Python37\site-packages\pandas\core\reshape\merge.py", line 87, in merge
    validate=validate,
  File "C:\Users\AA\AppData\Roaming\Python\Python37\site-packages\pandas\core\reshape\merge.py", line 652, in __init__
    ) = self._get_merge_keys()
  File "C:\Users\AA\AppData\Roaming\Python\Python37\site-packages\pandas\core\reshape\merge.py", line 1005, in _get_merge_keys
    right_keys.append(right._get_label_or_level_values(rk))
  File "C:\Users\AA\AppData\Roaming\Python\Python37\site-packages\pandas\core\generic.py", line 1580, in _get_label_or_level_values
    f"The label_axis_name label 'key' "
ValueError: The column label 'id' is not unique.
For a multi-index, the label must be a tuple with elements corresponding to each level.

这是非常令人惊讶和令人沮丧的 - 因为合并函数的“on”参数有一个元组作为参数,所以这里不应该有问题。 而且我需要使用合并功能,因为实际上,要合并的数据框更复杂,并且没有相同的 id 列。

你能告诉我如何解决这个问题并将两个数据框与多索引列合并吗?

【问题讨论】:

试试on =[('id','0')]? 非常感谢,它有效!我还是想知道为什么这里需要括号,但至少问题解决了。 索引级别的名称是('id','0'),是一个迭代。您需要将它包裹在一个列表中,以便 Pandas 将其解释为一列/索引级别,否则 Pandas 会将其理解为两列/索引级别。 【参考方案1】:

这里的问题是on可以使用一列或多列来合并两个数据框

所以当您通过on=('id', '0') 时,它认为您想要合并两个字段。写on=[('id', '0')] 消除了歧义。要合并的一列和指定为多索引一部分的两个标签:

df3 = pd.merge(df1, df2, on=[('id', '0')], how="outer")

【讨论】:

以上是关于熊猫多索引数据框合并问题的主要内容,如果未能解决你的问题,请参考以下文章

如何合并熊猫数据透视表中的多索引层?

ValueError 将多索引熊猫数据框转换为 Excel

将列添加到熊猫数据框以进行多索引

合并两个具有多索引的数据框

合并多索引数据框列表

加入/合并两个 Pandas 数据框并将列用作多索引