You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Pandas DataFrame两列中的唯一ID进行分组?

按指定ID列表分组DataFrame(ID仅出现在A/B列之一)

问题背景

现有长度为n的ID列表ids,以及包含列A、B、C的DataFrame df。已知ids中的每个ID仅会出现在A或B列中的一列(不会同时出现在两列),需要按这些ID对df进行分组,最终得到以ID为键、对应C列数据列表的结果。

示例

输入:

import pandas as pd
ids = [1, 2, 3, 4, 5]
df = pd.DataFrame({
    "A" : [1, 6, 3, 7, 5, 1],
    "B" : [8, 2, 9, 3, 10, 11],
    "C" : ["data1", "data2", "data3", "data4", "data5", "data6"]
})

期望输出:

{
    1: ["data1", "data6"],
    2: ["data2"],
    3: ["data3", "data4"],
    4: [],
    5: ["data5"]
}

之前尝试df.groupby(["A,B"]),但该写法会将A、B列作为联合分组键,无法达到需求,以下是几种简洁高效的解决方案:


解决方案

方法一:用np.where快速生成分组键(高效推荐)

利用numpy的向量化操作生成分组ID,比逐行apply效率高,适合大规模数据:

import numpy as np

# 标记A列ID是否在目标列表中
mask = df['A'].isin(ids)
# 生成分组ID:A列符合则取A,否则取B
df['group_id'] = np.where(mask, df['A'], df['B'])

# 过滤出目标ID的行,分组聚合C列并转字典
grouped = df[df['group_id'].isin(ids)].groupby('group_id')['C'].agg(list).to_dict()

# 补全无数据的ID,默认空列表
result = {id_val: grouped.get(id_val, []) for id_val in ids}

方法二:重塑数据后分组(代码简洁)

通过melt将A、B列转为单列,再进行分组,逻辑清晰:

# 重塑数据:将A、B列合并为group_id列,保留C列
melted_df = df.melt(id_vars=['C'], value_vars=['A', 'B'], value_name='group_id')

# 过滤目标ID并分组聚合
grouped = melted_df[melted_df['group_id'].isin(ids)].groupby('group_id')['C'].agg(list).to_dict()

# 补全无数据的ID
result = {id_val: grouped.get(id_val, []) for id_val in ids}

方法三:逐行提取分组ID(直观易懂)

用apply逐行判断并提取分组ID,适合中小规模数据,逻辑最直观:

# 逐行提取属于ids的ID(A或B)
df['group_id'] = df.apply(lambda row: row['A'] if row['A'] in ids else row['B'], axis=1)

# 过滤+分组+转字典
grouped = df[df['group_id'].isin(ids)].groupby('group_id')['C'].apply(list).to_dict()

# 补全无数据的ID
for id_val in ids:
    if id_val not in grouped:
        grouped[id_val] = []
result = grouped

注意事项

  • 由于题目保证每个ID仅出现在A或B列之一,无需处理同一行A/B均在ids中的冲突情况。
  • 数据量较大时优先选择方法一,np.where是向量化操作,远快于逐行apply;方法二的melt效率也不错,但会生成临时DataFrame。

内容的提问来源于stack exchange,提问作者Maria C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 23:03:09