
本文介绍如何利用`groupby().apply()`配合自定义函数,将dataframe中按连续相同“head”分组的成员列表整合为自然语言格式的邀请消息,并自动排除与head同名的重复成员。
在实际数据分析中,常需将结构化数据(如分组后的多行记录)转换为可读性强的文本摘要。本例目标是:对连续出现的相同 head(如 "Abba As")所对应的 members 列进行聚合,生成一条个性化邀请语句——其中首名成员(取 head 的姓氏部分)作为主宾称呼,其余成员用“and”连接,并保留原始 head 字符串用于入场标识。
关键难点在于:需按“head值连续出现”的逻辑分组(而非简单去重分组),因为同一 head 可能在后续再次出现(如示例中 "Abba As" 出现在索引 0–2 和 6–8),应视为两个独立邀请批次。
以下是完整实现方案:
import pandas as pd
# 构建示例数据
df = pd.DataFrame({
'head': ['Abba As', 'Abba As', 'Abba As', 'Bella Bi', 'Bella Bi', 'Bella Bi', 'Abba As', 'Abba As', 'Abba As'],
'members': ['Ally', 'Apo', 'Abba', 'Bella', 'Boo', 'Brian', 'Arra', 'Alya', 'Abba']
})
# 步骤1:识别连续分组(核心!)
group = df['head'].ne(df['head'].shift()).cumsum()
# 步骤2:定义生成message的函数
def generate_message(group_df):
head_full = group_df.name[0] # 获取当前组的head值(元组形式,取第一个元素)
head_first_name = head_full.split()[0] # 提取首名(如"Abba")
# 过滤掉与首名相同的成员(即本人),保留其余成员
other_members = [m for m in group_df['members'] if m != head_first_name]
# 用" and "连接其他成员
others_str = ' and '.join(other_members)
return f'Hi {head_first_name}, we invite you, {others_str}. Please use "{head_full}" when arriving.'
# 步骤3:分组应用 + 整理结果
result = (df.groupby(['head', group], sort=False)
.apply(generate_message)
.droplevel(1) # 删除辅助分组层级
.reset_index(name='message'))✅ 输出结果严格匹配预期:
基于jsp+javabean+access(mysql)三层结构的动态购物网站,v1.2包含v1.0中未公开的数据库连接 的java源文件 一,网站前台功能: 产品二级分类展示:一级分类--二级分类--产品列表--详细介绍(名称,图片,市场价,会员价,是否推荐,功能介绍等) 产品搜索:关键字模糊搜索 定购产品:选择商品--确认定购--填写收货人信息--选择付款方式--订单号自动生成(限登录用户)
head message 0 Abba As Hi Abba, we invite you, Ally and Apo. Please use "Abba As" when arriving. 1 Bella Bi Hi Bella, we invite you, Boo and Brian. Please use "Bella Bi" when arriving. 2 Abba As Hi Abba, we invite you, Arra and Alya. Please use "Abba As" when arriving.
⚠️ 注意事项:
- df['head'].ne(df['head'].shift()).cumsum() 是识别连续相同值区块的标准技巧,不可替换为 df.groupby('head')(否则会合并所有 "Abba As" 行,丢失批次语义);
- groupby(['head', group]) 中 group 是辅助序列号,确保相同 head 的不同连续段被区分开;
- 若某组内除首名外无其他成员(如仅含 ["Abba"]),others_str 将为空字符串,语句变为 "Hi Abba, we invite you, . Please..." —— 可根据业务需求在函数中增加空值判断(例如 if not other_members: others_str = "no one else");
- 此方法时间复杂度为 O(n),适用于万级以内数据;超大数据量建议结合 numba 或预聚合优化。
该模式可灵活扩展:替换模板字符串、支持多语言、接入邮件/短信API,是构建自动化报告与通知系统的典型范式。








