请求开发函数:按mobileNumber统计客户首选商品、平均营收及最新交易
客户交易统计函数开发
需求说明
针对每个以mobileNumber标识的客户,完成以下三项统计:
- 确定首选商品:
- 首选商品为购买数量最多的商品;
- 若多个商品购买数量相同,则选择Net Revenue总额最高的商品;
- 若上述两项均相同,则保留所有符合条件的商品,用逗号分隔。
- 计算平均Net Revenue:该客户所有交易的Net Revenue平均值;
- 获取最新交易日期:该客户所有交易中最晚的日期,格式为
YYYY-MM-DD。
数据样例
| mobileNumber | smartcard | country | item | Net Revenue | transaction date |
|---|---|---|---|---|---|
| 253717011202 | 25106064745190900 | Latvia | GOLD | 6779.661017 | 26/06/2021 |
| 253717011202 | 25106064745190900 | Latvia | SILVER | 5084.745763 | 17/06/2021 |
| 253717011202 | 25106064745190900 | Latvia | EXTRA | 2542.372881 | 09/04/2021 |
| 253717011202 | 25106064745190900 | Latvia | EXTRA | 2542.372881 | 10/03/2021 |
| 253717011202 | 25106064745190900 | Latvia | EXTRA | 2542.372881 | 18/02/2020 |
| 2530727013202 | 2510606474519120 | Sudan | GOLD | 2542.372881 | 09/04/2021 |
| 2530727013202 | 2510606474519120 | Sudan | GOLD | 2542.372881 | 10/03/2021 |
| 2530727013202 | 2510606474519120 | Sudan | EXTRA | 2542.372881 | 18/02/2020 |
| 12345678910 | 2311607474519120 | Zambia | GOLD | 2542.372881 | 09/04/2021 |
| 12345678910 | 2311607474519120 | Zambia | GOLD | 2542.372881 | 10/03/2021 |
| 12345678910 | 2311607474519120 | Zambia | EXTRA | 2542.372881 | 18/02/2020 |
| 12345678910 | 2311607474519120 | Zambia | EXTRA | 2542.372881 | 18/02/2020 |
预期输出
| mobileNumber | smartcard | country | preferred_item | average_revenue | last_transaction |
|---|---|---|---|---|---|
| 2530727013202 | 2510606474519120 | Sudan | GOLD | 2542.372881 | 2021-04-09 |
| 12345678910 | 2311607474519120 | Zambia | EXTRA, GOLD | 2542.372881 | 2021-04-09 |
| 253717011202 | 25106064745190900 | Latvia | EXTRA | 3898.305085 | 2021-06-26 |
生成测试数据代码
import pandas as pd df = pd.DataFrame( { 'mobileNumber': ['253717011202', '253717011202', '253717011202', '253717011202', '253717011202', '2530727013202', '2530727013202', '2530727013202', '12345678910', '12345678910', '12345678910', '12345678910'], 'smartcard': ['25106064745190900', '25106064745190900', '25106064745190900', '25106064745190900', '25106064745190900', '2510606474519120', '2510606474519120', '2510606474519120', '2311607474519120', '2311607474519120', '2311607474519120', '2311607474519120'], 'country': ['Latvia', 'Latvia', 'Latvia', 'Latvia', 'Latvia', 'Sudan', 'Sudan', 'Sudan', 'Zambia', 'Zambia', 'Zambia', 'Zambia'], 'item': ['GOLD', 'SILVER', 'EXTRA', 'EXTRA', 'EXTRA', 'GOLD', 'GOLD', 'EXTRA', 'GOLD', 'GOLD', 'EXTRA', 'EXTRA'], 'Net Revenue': [6779.661017, 5084.745763, 2542.372881, 2542.372881, 2542.372881, 2542.372881, 2542.372881, 2542.372881, 2542.372881, 2542.372881, 2542.372881, 2542.372881], 'transaction date': ['26/06/2021', '17/06/2021', '09/04/2021', '10/03/2021', '18/02/2020', '09/04/2021', '10/03/2021', '18/02/2020', '09/04/2021', '10/03/2021', '18/02/2020', '18/02/2020'], } ) expected_output = pd.DataFrame( { 'mobileNumber': [253717011202, 2530727013202, 12345678910], 'smartcard': [25106064745190900, 2510606474519120, 2311607474519120], 'country': ['Latvia', 'Sudan', 'Zambia'], 'preferred_item': ['EXTRA', 'GOLD', 'EXTRA, GOLD'], 'average_revenue': [3898.305085, 2542.372881, 2542.372881], 'last_transaction': ['2021-06-26', '2021-04-09', '2021-04-09'], } )
解决方案代码
import pandas as pd def calculate_customer_stats(df): # 转换交易日期为datetime类型 df['transaction date'] = pd.to_datetime(df['transaction date'], format='%d/%m/%Y') # 1. 计算每个客户的平均Net Revenue和最新交易日期 customer_summary = df.groupby(['mobileNumber', 'smartcard', 'country']).agg( average_revenue=('Net Revenue', 'mean'), last_transaction=('transaction date', 'max') ).reset_index() # 格式化最新交易日期为YYYY-MM-DD customer_summary['last_transaction'] = customer_summary['last_transaction'].dt.strftime('%Y-%m-%d') # 2. 统计每个客户下各商品的购买数量和Net Revenue总额 item_stats = df.groupby(['mobileNumber', 'item']).agg( purchase_count=('item', 'count'), total_revenue=('Net Revenue', 'sum') ).reset_index() # 3. 筛选每个客户的首选商品 def get_preferred_items(group): # 按购买数量降序,总营收降序排序 sorted_group = group.sort_values(['purchase_count', 'total_revenue'], ascending=False) # 获取最高的购买数量和对应总营收 max_count = sorted_group['purchase_count'].iloc[0] max_revenue = sorted_group[sorted_group['purchase_count'] == max_count]['total_revenue'].iloc[0] # 筛选符合条件的商品 preferred = sorted_group[(sorted_group['purchase_count'] == max_count) & (sorted_group['total_revenue'] == max_revenue)]['item'] # 用逗号分隔多个商品 return ', '.join(sorted(preferred.unique())) preferred_items = item_stats.groupby('mobileNumber').apply(get_preferred_items).reset_index(name='preferred_item') # 4. 合并结果 final_result = pd.merge(customer_summary, preferred_items, on='mobileNumber') # 转换mobileNumber和smartcard为整数类型(匹配预期输出格式) final_result['mobileNumber'] = final_result['mobileNumber'].astype(int) final_result['smartcard'] = final_result['smartcard'].astype(int) # 调整列顺序匹配预期输出 final_result = final_result[['mobileNumber', 'smartcard', 'country', 'preferred_item', 'average_revenue', 'last_transaction']] return final_result # 测试函数 result = calculate_customer_stats(df) print(result) # 验证与预期输出是否一致 print(pd.testing.assert_frame_equal(result, expected_output, check_dtype=False))
代码说明
- 日期转换:将交易日期字符串转为datetime类型,方便后续计算最新日期。
- 客户基础统计:按
mobileNumber、smartcard、country分组,计算平均营收和最新交易日期,并格式化日期。 - 商品统计:按客户和商品分组,统计每个商品的购买数量和总营收。
- 首选商品筛选:对每个客户的商品统计结果排序,筛选出购买数量最多、总营收最高的商品,多个符合条件时用逗号分隔。
- 结果合并:将基础统计和首选商品结果合并,调整列顺序和数据类型,匹配预期输出。
内容的提问来源于stack exchange,提问作者Mwai.John
相关产品推荐
相关产品推荐

