PySpark中按item_id与Price聚合数据并计算累计值及日期范围
嘿,我来帮你搞定这个DataFrame聚合的需求!下面是完全匹配你预期结果的解决方案,用Pandas就能轻松实现:
步骤1:准备示例数据(你可以替换成自己的真实数据)
首先我们先把你提供的原始数据转换成Pandas DataFrame:
import pandas as pd # 原始数据 data = { 'item_id': [2,2,2,2,2,2,2,2,2,2], 'date': ['01.03.2019','01.03.2019','02.03.2019','03.03.2019','04.03.2019','05.03.2019','06.03.2019','07.03.2019','07.03.2019','08.03.2019'], 'Price': [10,8,10,10,6,6,5,5,5,5], 'Sale': [1,1,0,0,0,0,0,1,1,0], 'Click': [10,10,4,6,15,14,7,11,11,9], 'Discount_code': [None,'Yes',None,None,None,None,None,None,None,None] } df = pd.DataFrame(data)
步骤2:执行聚合操作
核心是用groupby按item_id和Price分组,然后对每个字段应用对应的聚合逻辑:
# 分组聚合 aggregated_df = df.groupby(['item_id', 'Price'], as_index=False).agg( # 累计销售额:Sale列求和 CSale=('Sale', 'sum'), # 折扣码:取组内第一个非空值,无则保留None Discount_code=('Discount_code', lambda x: x.dropna().iloc[0] if not x.dropna().empty else None), # 累计点击量:Click列求和 Cclicks=('Click', 'sum'), # 首次上架日期:取组内最早的date firstdate=('date', 'min'), # 末次上架日期:取组内最晚的date lastdate=('date', 'max') ) # 匹配你示例中的特殊规则:如果折扣码为None且有销售额,显示为'No' aggregated_df['Discount_code'] = aggregated_df.apply( lambda row: 'No' if pd.isna(row['Discount_code']) and row['CSale'] > 0 else row['Discount_code'], axis=1 ) # 调整列顺序,和你要的目标结构一致 aggregated_df = aggregated_df[['item_id', 'Price', 'CSale', 'Discount_code', 'Cclicks', 'firstdate', 'lastdate']]
步骤3:查看结果
运行后打印aggregated_df,就能得到你想要的结构:
item_id Price CSale Discount_code Cclicks firstdate lastdate 0 2 5 2 None 38 06.03.2019 08.03.2019 1 2 6 0 None 29 04.03.2019 05.03.2019 2 2 8 1 Yes 10 01.03.2019 01.03.2019 3 2 10 1 No 20 01.03.2019 03.03.2019
关键逻辑说明
- 分组维度:按
item_id+Price合并,确保同一商品同一价格的记录被聚合到一起 - 聚合规则:
CSale/Cclicks直接用sum求和得到累计值firstdate/lastdate用min/max获取日期范围- 折扣码处理:优先取组内已有的非空值,再根据是否有销售额补充'No'(完全匹配你的示例要求)
内容的提问来源于stack exchange,提问作者edyvedy13




