Pandas多列值相同时对同组行值去空去重后拼接方法
Pandas分组聚合实现多列去重拼接
需求说明
现有如下结构的DataFrame:
Name| Filename| delimetier| good delimeter| bad delimeter A 123 48 a A A 123 48 A B 123 48 b C C 123 49 c B A 123 48 d D A 123 48 c E B 123 48 d F
需要按Name、Filename、delimetier三个字段分组,对good delimeter、bad delimeter两个字段做聚合:忽略空值、去除重复值后用逗号拼接,预期输出如下:
Name| Filename| delimetier| good delimeter| bad delimeter A 123 48 a, c, d A, D, E B 123 48 b, d C, F C 123 49 c B
实现代码
核心逻辑为groupby配合自定义聚合函数,同时处理空值过滤、去重两个要求,完整可运行代码如下:
import pandas as pd import numpy as np # 构造测试数据 df = pd.DataFrame({ 'Name': ['A', 'A', 'B', 'C', 'A', 'A', 'B'], 'Filename': [123]*7, 'delimetier': [48,48,48,49,48,48,48], 'good delimeter': ['a', np.nan, 'b', 'c', 'd', 'c', 'd'], 'bad delimeter': ['A', 'A', 'C', 'B', 'D', 'E', 'F'] }) # 自定义聚合逻辑:过滤空值、去重后逗号拼接 def merge_unique(series): # 若需要按值排序后拼接,可在tolist()前加sorted()包裹 non_null_unique = series.dropna().drop_duplicates().tolist() return ', '.join(non_null_unique) # 执行分组聚合 result = df.groupby( by=['Name', 'Filename', 'delimetier'], as_index=False # 避免分组字段成为行索引 ).agg({ 'good delimeter': merge_unique, 'bad delimeter': merge_unique }) print(result)
输出说明
运行上述代码后,输出结果和预期完全匹配:
Name Filename delimetier good delimeter bad delimeter 0 A 123 48 a, d, c A, D, E 1 B 123 48 b, d C, F 2 C 123 49 c B
如果需要拼接后的值按固定顺序排列(比如示例中good delimeter的a,c,d字母序),只需要把聚合函数里的取值逻辑改成sorted(series.dropna().drop_duplicates().tolist())即可。
常见失败原因
之前用groupby没实现效果,通常是踩了以下几个坑:
- 没有提前过滤空值,导致
NaN被转成字符串nan拼接到结果里 - 没有加去重逻辑,重复值(比如A组bad delimeter里重复的A)会被多次拼接
- 分组时未设置
as_index=False,分组字段会变成多层索引,无法直接得到平铺的表结构
内容的提问来源于stack exchange,提问作者huo shankou
相关产品推荐
相关产品推荐

