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

如何用Pandas GroupBy按单列分组,聚合列最值并保留其他列且无多级列

问题描述

现有如下Pandas DataFrame:

import pandas as pd

account_number = [1234, 5678, 9012, 1234.0, 5678, 9012, 1234.0, 5678, 9012, 1234.0, 5678, 9012]
client_name = ["Ford", "GM", "Honda", "Ford", "GM", "Honda", "Ford", "GM", "Honda", "Ford", "GM", "Honda"]
database = ["DB_Ford", "DB_GM", "DB_Honda", "DB_Ford", "DB_GM", "DB_Honda", "DB_Ford", "DB_GM", "DB_Honda", "DB_Ford", "DB_GM", "DB_Honda"]
server = ["L01SQL04", "L01SQL08", "L01SQL12", "L01SQL04", "L01SQL08", "L01SQL12", "L01SQL04", "L01SQL08", "L01SQL12", "L01SQL04", "L01SQL08", "L01SQL12"]
order_num = [2145479, 2145506, 2145534, 2145603, 2145658, 2429513, 2145489, 2145516, 2145544, 2145499, 2145526, 2145554]
customer_dob = ["1967-12-01", "1963-07-09", "1986-12-05", "1967-11-01", None, "1986-12-05", "1967-12-01", "1963-07-09", "1986-12-05", "1967-12-01", "1963-07-09", "1986-12-04"]
purchase_date = ["2022-06-18", "2022-04-11", "2021-01-18", "2022-06-20", "2022-04-11", "2021-01-18", "2022-06-22", "2022-04-13", "2021-01-18", "2022-06-24", "2022-04-18", "2021-01-18"]

d = {
    "account_number": account_number, 
    "client_name" : client_name,
    "database" : database,
    "server" : server,
    "order_num" : order_num,
    "customer_dob" : customer_dob,
    "purchase_date" : purchase_date,
}
df = pd.DataFrame(data=d)

dates = ["customer_dob", "purchase_date"]
for date in dates:
    df[date] = pd.to_datetime(df[date])

需求是:按account_number分组,对customer_dob取最大值、purchase_date取最小值,同时保留其他列(这些列在同一account_number下值均一致),但之前的尝试出现多级列或数据问题,需要得到单级列的完整结果。

之前的尝试问题:

  • 第一种尝试指定部分列后聚合,生成多级列且无法看到日期列的实际值:
result = df.groupby("account_number")["client_name", "database", "server", "order_num"].agg({"customer_dob": "max", "purchase_date": "min"}).reset_index()
  • 第二种尝试包含日期列,但聚合参数写错(使用了不存在的patient_dob和insert_date列名),仍生成多级列且数据重复:
result = df.groupby("account_number")["client_name", "database", "server", "order_num", "customer_dob", "purchase_date"].agg(
    {"patient_dob": "max", "insert_date": "min"}).reset_index()
解决方案

方法一:聚合日期列后与去重数据合并

先按需求聚合日期列,再将原数据中每个account_number对应的唯一其他列信息合并:

# 聚合日期列
date_agg = df.groupby("account_number").agg(
    customer_dob=("customer_dob", "max"),
    purchase_date=("purchase_date", "min")
).reset_index()

# 获取每个account_number对应的唯一其他列数据
other_cols = df.drop(columns=["customer_dob", "purchase_date"]).drop_duplicates("account_number")

# 合并结果
result = pd.merge(other_cols, date_agg, on="account_number")

方法二:直接在agg中指定所有列的聚合规则

因为其他列在同一account_number下值一致,可用first/last/max等聚合方式(结果相同),同时指定日期列的规则:

result = df.groupby("account_number").agg(
    client_name=("client_name", "first"),
    database=("database", "first"),
    server=("server", "first"),
    order_num=("order_num", "first"),  # 注意:若order_num同一账号下有不同值,需根据业务需求调整聚合方式
    customer_dob=("customer_dob", "max"),
    purchase_date=("purchase_date", "min")
).reset_index()

方法三:用transform生成聚合列后去重

通过transform将聚合后的日期值广播到每一行,再去重得到每个账号的唯一记录:

# 生成聚合后的日期列
df["customer_dob_max"] = df.groupby("account_number")["customer_dob"].transform("max")
df["purchase_date_min"] = df.groupby("account_number")["purchase_date"].transform("min")

# 保留需要的列并去重
result = df.drop(columns=["customer_dob", "purchase_date"]).rename(
    columns={"customer_dob_max": "customer_dob", "purchase_date_min": "purchase_date"}
).drop_duplicates("account_number")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:30:48