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

如何仅基于公共列值执行groupby分组操作

Pandas分组:按共享Type集合与Alias的Code、Name聚合

需求明确

需要将DataFrame中的行进行分组,仅当不同行的Name和Alias完全相同,且对应的Type集合完全一致时,将这些行归为一组,最终输出包含Code、Name、Alias及对应Type集合的结果表。例如:

  • 原始数据中Name="cardio"、Alias="[Card,Cardio]"且覆盖Type A/B/C的行,归为一组;
  • Name="Heart"、Alias="[Heart]"且覆盖Type A/C的行,单独归为一组。

补充:原始数据中Type E对应的Code为2。

实现代码

假设原始DataFrame名为df,以下是完整实现逻辑:

import pandas as pd

# 模拟符合描述的原始数据
data = [
    {"Type": "A", "Code": 1, "Name": "cardio", "Alias": "[Card,Cardio]"},
    {"Type": "B", "Code": 1, "Name": "cardio", "Alias": "[Card,Cardio]"},
    {"Type": "C", "Code": 1, "Name": "cardio", "Alias": "[Card,Cardio]"},
    {"Type": "A", "Code": 3, "Name": "Heart", "Alias": "[Heart]"},
    {"Type": "C", "Code": 3, "Name": "Heart", "Alias": "[Heart]"},
    {"Type": "E", "Code": 2, "Name": "Liver", "Alias": "[Liver]"},
]
df = pd.DataFrame(data)

# 1. 生成(Name, Alias)到对应Type集合的映射(用frozenset保证可哈希)
type_group_mapping = df.groupby(["Name", "Alias"])["Type"].apply(frozenset).reset_index(name="Type_Group")

# 2. 将分组标识合并回原始数据
df_with_group_key = pd.merge(df, type_group_mapping, on=["Name", "Alias"])

# 3. 按Type_Group、Alias、Name聚合,得到最终结果
result = df_with_group_key.groupby(["Type_Group", "Alias", "Name"]).agg(
    Code=("Code", "first"),  # 同一分组内Code一致,取首个值即可
    Types=("Type", lambda x: sorted(set(x)))  # 整理为有序的Type列表
).reset_index(drop=True)[["Code", "Name", "Alias", "Types"]]

print(result)

代码说明

  • 使用frozenset存储Type集合:因为普通集合不可哈希,无法作为groupby的分组键,而frozenset是不可变的可哈希类型;
  • 聚合逻辑:同一分组内的Code是唯一的,因此用first提取;Type集合整理为有序列表,提升可读性;
  • 合并映射表:确保每一行都能关联到自己所属的Type分组,为最终聚合做准备。

问题表述优化建议

  1. 明确核心逻辑:直接点明「分组依据是(Name+Alias)组合对应的Type集合完全相同」,避免模糊描述;
  2. 补充数据示例:给出原始数据的具体行(如上述模拟数据)和期望的输出结果行,用表格形式展示更直观;
  3. 列信息明确:说明各列的数据类型(如Code是整数、Type是字符串枚举),减少歧义;
  4. 特殊信息前置:将「Type E的Code为2」这类补充信息放在原始数据示例中,而非单独说明。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 17:47:33