Pandas按order_num分组将product_code转为列表并保留其余列的实现方案
实现方案
你可以通过groupby的多列不同聚合规则直接实现,不需要把非分组字段加入分组条件,也不需要额外做表拼接:
方法1:单轮groupby多规则聚合(推荐)
直接在agg方法中为不同列指定不同的聚合逻辑,非分组字段统一按你需要的规则取值即可(如果同一个order_num对应的其他字段值唯一,取first/last效果和加入分组条件完全一致):
import pandas as pd # 你可以直接用自己的原始df,这里是补全timestamp的测试数据 data={'order_num':[123,234,356,123,234,356], 'email':['abc@gmail.com','pqr@hotmail.com','xyz@yahoo.com','abc@gmail.com','pqr@hotmail.com','xyz@gmail.com'], 'product_code':['rdcf1','6fgxd','2sdfs','34fgdf','gvwt5','5ganb'], 'timestamp':['2024-01-01 10:00','2024-01-01 10:05','2024-01-01 10:10','2024-01-01 10:00','2024-01-01 10:05','2024-01-01 10:15']} df=pd.DataFrame(data,columns=['order_num','email','product_code','timestamp']) # 核心实现代码 result = df.groupby('order_num', as_index=False).agg( product_code=('product_code', list), # 仅对product_code做列表聚合 email=('email', 'first'), # 保留email原值,取分组内第一个值 timestamp=('timestamp', 'first') # 保留timestamp原值,取分组内第一个值 # 其他需要保留的字段都可以按照 输出列名=('原列名', 取值规则) 的格式添加 ).sort_values('timestamp').reset_index(drop=True)
如果同一个order_num对应的非分组字段存在多个不同值,你可以调整取值规则:比如换成'last'取分组最后一个值,或者换成lambda x: x.mode()[0]取众数,自定义规则即可。
方法2:分组聚合后和原表去重结果拼接
如果需要保留的字段非常多,不想逐个在agg里声明,可以用这个方法:
# 1. 仅按order_num分组聚合product_code grouped_product = df.groupby('order_num', as_index=False)['product_code'].agg(product_code=list) # 2. 原表去掉product_code后按order_num去重,保留所有其他字段 other_cols = df.drop('product_code', axis=1).drop_duplicates('order_num', keep='first') # 3. 合并后按timestamp排序 result = pd.merge(grouped_product, other_cols, on='order_num').sort_values('timestamp').reset_index(drop=True)
内容的提问来源于stack exchange,提问作者yorunome
相关产品推荐
相关产品推荐

