使用一系列列合并两个 DataFrame(在 ID 上右侧,在多个 ID 上左侧)

Posted

技术标签:

【中文标题】使用一系列列合并两个 DataFrame(在 ID 上右侧,在多个 ID 上左侧)【英文标题】:Merging two DataFrame using a range of columns (Right on ID and left on multiple IDs) 【发布时间】:2021-12-28 21:21:15 【问题描述】:

我想使用id 从两个df 创建一个数据集。问题是在第二个 df 上,id 不在单个列中。 id 值可以位于不同的列中。

merged=pd.merge(df1, df2, left_on=['id','month','year'], right_on=['id_name','id_surname','id_first_name', month','year'], how="left")

所有id 变量都是字母数字。

但我收到错误:

ValueError: len(right_on) must equal len(left_on)

理想情况下,我想测试 id 是否在其他三列之一中 ids ,并在该列上相应地合并。也许某种 vlookup() 函数(来自 excel)允许在表数组的范围内查找键值。有什么想法吗?

【问题讨论】:

您不能加入不同数量的键。您需要为第二个数据框创建一个列,其中包含您需要的所有 ID。您还可以尝试连续执行三个连接,对第二个 df 的每个 'id_name'、'id_surname'、'id_first_name' 列执行一次。请提供您的数据框示例,以便我提供更多帮助:) 【参考方案1】:

假设我们有以下两个数据框:

import pandas as pd
import numpy as np

df1 = pd.DataFrame(
    
        "id": [1, 2, 3],
        "month": ["Jan", "Mar", "Apr"],
        "year": ["2022", "2020", "2021"],
        "column_A": ["test", "test_", "test__"]
    
)


df2 = pd.DataFrame(
    
        "id_name": [1, np.NaN, np.NaN],
        "id_surname": [np.NaN, 2, np.NaN],
        "id_first_name": [np.NaN, np.NaN, 3],
        "month": ["Jan", "Mar", "Apr"],
        "year": ["2022", "2020", "2021"],
        "column_B": ["check", "check_", "check__"]
    
)

第二个数据框将是:

   id_name  id_surname  id_first_name month  year column_B
0      1.0         NaN            NaN   Jan  2022   check
1      NaN         2.0            NaN   Mar  2020   check_
2      NaN         NaN            3.0   Apr  2021   check__

您可以通过保留三列 id_name, id_surname, id_first_name 中的所有非 NaN 值来为第二个数据帧创建一个新列 id。从id_name 列开始,用id_surname 的非Nans 值填充其NaN,然后​​用id_first_name 的非NaN 填充剩余的NaN。这样做的代码是:

df2["id"] = df2["id_name"].fillna(df2["id_surname"]).fillna(df2["id_first_name"])

这将为df2 创建列id

   id_name  id_surname  id_first_name month  year column_B   id
0      1.0         NaN            NaN   Jan  2022   check    1.0
1      NaN         2.0            NaN   Mar  2020   check_   2.0
2      NaN         NaN            3.0   Apr  2021   check__  3.0

最后,您可以通过以下方式合并:

merged = pd.merge(
    df1,
    df2,
    left_on=["id", "month", "year"],
    right_on=["id", "month", "year"],
    how="left",
)

结果将是:

   id month  year column_A  id_name  id_surname  id_first_name column_B
0   1   Jan  2022     test      1.0         NaN            NaN   check
1   2   Mar  2020    test_      NaN         2.0            NaN   check_
2   3   Apr  2021   test__      NaN         NaN            3.0   check__

【讨论】:

Pandas fillna 函数正是我所需要的。我什至没有想到!

以上是关于使用一系列列合并两个 DataFrame(在 ID 上右侧,在多个 ID 上左侧)的主要内容,如果未能解决你的问题,请参考以下文章

如何获取一系列列作为集合?

如何通过基于名称而不是索引选择一系列列和行来对数据框进行切片?

比较两个序列列,并基于条件将元素添加到 Dataframe

在特定 ID 列上合并两个 DataFrame(数据集)但具有日期条件

合并两个具有列表的数据集并在合并后使用 pandas 保留列表

R语言dplyr包使用bind_rows函数纵向合并两个dataframe(行生长)使用bind_cols函数横向合并两个dataframe(列生长)