如何在Pandas DataFrame分组聚合时合并列表类型列?
问题描述
我有一个包含3列的Pandas DataFrame,其中C2列的值为列表类型,部分行存在NaN值。希望按C1列分组后实现两个聚合需求:
- 将C2列的列表聚合为单个扁平且去重的列表
- 将C3列的字符串聚合为列表
原始DataFrame:
| C1 | C2 | C3 |
|---|---|---|
| 1 | ['A','B'] | Hi |
| 2 | NaN | Po |
| 1 | ['B','C'] | Yo |
| 2 | ['D','E'] | Yup |
期望聚合结果:
| C1 | C2 | C3 |
|---|---|---|
| 1 | ['A','B','C'] | ['Hi','Yo'] |
| 2 | ['D','E'] | ['Po','Yup'] |
直接使用聚合函数传入list参数时,C2列会得到嵌套列表,不符合预期:
| C1 | C2 | C3 |
|---|---|---|
| 1 | [['A','B'],['B','C']] | ['Hi','Yo'] |
| 2 | ['D','E'] | ['Po','Yup'] |
解决方案
步骤1:构造原始DataFrame(用于复现场景,可跳过)
import pandas as pd import numpy as np df = pd.DataFrame({ 'C1': [1, 2, 1, 2], 'C2': [['A','B'], np.nan, ['B','C'], ['D','E']], 'C3': ['Hi', 'Po', 'Yo', 'Yup'] })
步骤2:自定义C2列的聚合函数
针对C2列的需求,编写聚合函数实现过滤NaN→扁平化列表→去重的逻辑:
def flatten_unique(lst): flat_list = [] for item in lst: # 跳过NaN值 if pd.notna(item): flat_list.extend(item) # 去重同时保留元素首次出现的顺序(Python 3.7+原生支持) return list(dict.fromkeys(flat_list))
步骤3:分组聚合
调用groupby和agg方法,为不同列指定对应的聚合逻辑:
result = df.groupby('C1').agg({ 'C2': flatten_unique, 'C3': list }).reset_index()
最终结果
执行上述代码后,result即为期望的聚合结果:
| C1 | C2 | C3 |
|---|---|---|
| 1 | ['A','B','C'] | ['Hi','Yo'] |
| 2 | ['D','E'] | ['Po','Yup'] |
补充说明
- 如果不需要保留元素先后顺序,可将去重逻辑替换为
list(set(flat_list)),但会打乱原有顺序 - 用
pd.notna(item)判断NaN,避免直接用is not None(Pandas的NaN是特殊数值类型)
内容的提问来源于stack exchange,提问作者BrownBatman
相关产品推荐
相关产品推荐

