Pandas多列复杂聚合:生成订单商品对并统计频次与营收总和
商品组合对的频次与营收统计问题
数据集
import pandas as pd from itertools import combinations d = {'Order_ID': ['001', '001', '002', '003', '003', '003', '004', '004'], 'Products': ['Apple', 'Pear', 'Banana', 'Apple', 'Pear', 'Banana', 'Apple', 'Pear'], 'Revenue': [15, 10, 5, 25, 15, 10, 5, 30]} df = pd.DataFrame(data=d)
数据集输出:
Order_ID Products Revenue 0 001 Apple 15 1 001 Pear 10 2 002 Banana 5 3 003 Apple 25 4 003 Pear 15 5 003 Banana 10 6 004 Apple 5 7 004 Pear 30
目标输出
需要统计所有交易中商品组合对的出现频次及对应营收总和,目标结果如下:
d = {'Groups': ['(Apple, Pear)', '(Banana, Apple)', '(Banana, Pear)'], 'Frequency': [3, 1, 1], 'Revenue': [100, 35, 40]} df2 = pd.DataFrame(data=d)
输出展示:
Groups Frequency Revenue 0 (Apple, Pear) 3 100 1 (Banana, Apple) 1 35 2 (Banana, Pear) 1 40
现有代码问题
已实现获取商品组合对及其频次,但无法同时统计营收:
def find_pairs(x): return pd.Series(list(combinations(set(x), 2))) df_group = df.groupby('Order_ID')['Products'].apply(find_pairs).value_counts() df_group
需要实现:生成商品组合对后,按组合对分组,累加对应商品的营收总和。
解决方案
可以通过以下步骤实现:
- 按
Order_ID分组,同时保留Products和Revenue信息 - 对每个订单生成商品组合对,并计算该组合对对应商品的营收之和
- 最后按组合对分组,统计频次和营收总和
完整代码:
import pandas as pd from itertools import combinations d = {'Order_ID': ['001', '001', '002', '003', '003', '003', '004', '004'], 'Products': ['Apple', 'Pear', 'Banana', 'Apple', 'Pear', 'Banana', 'Apple', 'Pear'], 'Revenue': [15, 10, 5, 25, 15, 10, 5, 30]} df = pd.DataFrame(data=d) def process_order(group): # 获取当前订单的商品列表和对应营收 products = group['Products'].tolist() revenues = group['Revenue'].tolist() # 生成商品组合对并去重 pairs = list(set(combinations(products, 2))) # 计算每个组合对的营收总和 pair_revenues = [] for pair in pairs: rev_sum = revenues[products.index(pair[0])] + revenues[products.index(pair[1])] pair_revenues.append(rev_sum) # 返回组合对与对应营收的DataFrame return pd.DataFrame({ 'Groups': [str(pair) for pair in pairs], 'Revenue': pair_revenues }) # 按订单分组处理并合并结果 result_df = df.groupby('Order_ID').apply(process_order).reset_index(drop=True) # 统计每个组合对的频次与总营收 final_df = result_df.groupby('Groups').agg( Frequency=('Groups', 'count'), Revenue=('Revenue', 'sum') ).reset_index() # 调整列顺序匹配目标输出 final_df = final_df[['Groups', 'Frequency', 'Revenue']] print(final_df)
运行结果:
Groups Frequency Revenue 0 (Apple, Pear) 3 100 1 (Banana, Apple) 1 35 2 (Banana, Pear) 1 40
代码说明
process_order函数处理单个订单:生成不重复的商品组合对,计算每个组合对的营收(组合内两个商品的营收相加)- 先按订单分组处理所有交易,再对组合对二次分组,统计频次(组合对出现的订单数)和总营收
- 使用
set(pairs)避免同一订单内重复统计相同组合对
内容的提问来源于stack exchange,提问作者Iñaki Baglivo
相关产品推荐
相关产品推荐

