【Python】Pandas Groupby实战:从基础聚合到高级分析的20个场景

张开发
2026/6/1 14:24:11 15 分钟阅读
【Python】Pandas Groupby实战:从基础聚合到高级分析的20个场景
1. Pandas Groupby入门从数据分组到基础聚合第一次接触Pandas的groupby功能时我完全被它强大的数据处理能力震撼了。想象你手里有一堆杂乱无章的销售数据groupby就像个智能分类器能瞬间帮你把数据按不同维度整理得井井有条。举个例子如果你有全国各门店的销售记录groupby可以帮你快速统计出每个省份的销售总额或者每个产品类别的月销量变化。让我们从一个简单的电商数据集开始import pandas as pd import numpy as np # 模拟电商订单数据 np.random.seed(42) products [手机, 笔记本, 平板, 耳机, 智能手表] regions [华东, 华北, 华南, 西部] data pd.DataFrame({ 订单ID: range(1001, 1021), 产品: np.random.choice(products, 20), 地区: np.random.choice(regions, 20), 销售额: np.random.randint(100, 5000, 20), 数量: np.random.randint(1, 5, 20) })最基本的单列分组统计可以这样实现# 按地区统计销售总额 region_sales data.groupby(地区)[销售额].sum() print(region_sales)这个简单的操作背后Pandas实际上完成了三个关键步骤拆分(Split)按照指定列的值将DataFrame拆分成多个子集应用(Apply)对每个子集应用聚合函数如sum、mean等合并(Combine)将各组的计算结果合并成一个新的DataFrame当我们需要同时查看多个统计指标时agg()函数就派上用场了# 多指标聚合分析 product_stats data.groupby(产品).agg({ 销售额: [sum, mean, max], 数量: sum }) print(product_stats)2. 电商数据分析实战用户分群与销售透视在真实的电商分析场景中groupby能发挥更大的作用。我曾经处理过一个用户行为数据集需要分析不同用户群体的购买特征。通过groupby配合多个聚合函数我们很快发现了高价值用户的消费模式。假设我们有以下用户行为数据user_data pd.DataFrame({ 用户ID: [U1001, U1002, U1003, U1001, U1002, U1003, U1001], 注册日期: pd.to_datetime([2023-01-01, 2023-01-05, 2023-01-10, 2023-01-01, 2023-01-05, 2023-01-10, 2023-01-01]), 用户等级: [VIP, 普通, 普通, VIP, 普通, 普通, VIP], 订单金额: [580, 120, 350, 420, 90, 280, 660], 购买品类: [数码, 服饰, 家居, 美妆, 服饰, 数码, 数码] })用户价值分群分析可以这样做user_value user_data.groupby([用户ID, 用户等级]).agg( 总消费(订单金额, sum), 平均消费(订单金额, mean), 购买频次(订单金额, count) ).sort_values(总消费, ascendingFalse) print(user_value)更复杂的交叉分析也能轻松实现。比如分析不同用户等级在各品类的消费表现cross_analysis user_data.groupby([用户等级, 购买品类]).agg( 总销售额(订单金额, sum), 订单数(订单金额, count) ).unstack() print(cross_analysis)这里用到了unstack()方法将多级索引的聚合结果转换为更易读的表格形式。在实际项目中这种透视分析能帮我们快速发现业务机会比如发现VIP用户在数码品类的高消费倾向就可以针对性地设计促销活动。3. 高级分组技巧自定义函数与多级处理当基础聚合函数不能满足需求时groupby的灵活性才真正显现出来。我曾经遇到一个需要计算移动平均的场景通过自定义函数完美解决了问题。考虑以下时间序列数据date_rng pd.date_range(start2023-01-01, end2023-01-10, freqD) time_series pd.DataFrame({ 日期: np.random.choice(date_rng, 50), 产品线: np.random.choice([A, B, C], 50), 销售额: np.random.randint(100, 1000, 50) })时间窗口计算示例# 按产品线计算3日移动平均 def rolling_avg(group): return group.set_index(日期).sort_index()[销售额].rolling(3D).mean() moving_avg time_series.groupby(产品线).apply(rolling_avg) print(moving_avg.unstack())更复杂的分组过滤也很有用。比如找出销售额持续增长的品类def is_increasing(s): return s.diff().dropna().gt(0).all() sales_trend time_series.groupby([产品线, pd.Grouper(key日期, freqW-MON)])[销售额].sum() result sales_trend.groupby(level0).filter(is_increasing) print(result)多级分组处理时pd.Grouper非常实用。我曾经用它处理过按周、按月、按季度的多层次分析需求# 多级时间分组分析 multi_level time_series.groupby([ 产品线, pd.Grouper(key日期, freqW) ]).agg({ 销售额: [sum, count] }) print(multi_level)4. 性能优化与实战经验分享在大数据集上使用groupby时性能问题不容忽视。我曾在处理百万级订单数据时踩过不少坑总结出几点优化经验1. 选择合适的分组方式# 低效做法分组后选择列 slow large_df.groupby(category)[value].mean() # 高效做法先选择列再分组 fast large_df[[category, value]].groupby(category).mean()2. 避免不必要的排序# 如果不需要排序结果关闭sort可以提升性能 fast_groupby large_df.groupby(category, sortFalse).mean()3. 使用更高效的聚合函数# 对于大数据集numpy的聚合函数通常比pandas原生更快 optimized df.groupby(key).agg( mean_value(value, np.mean), sum_value(value, np.sum) )4. 分块处理超大数据集# 处理超大数据集的分块策略 chunk_size 100000 results [] for chunk in pd.read_csv(huge_file.csv, chunksizechunk_size): chunk_result chunk.groupby(category).sum() results.append(chunk_result) final_result pd.concat(results).groupby(level0).sum()真实项目中数据往往不够干净。处理缺失值时需要注意groupby的行为# 包含缺失值的数据处理 data_with_nan data.copy() data_with_nan.loc[::5, 销售额] np.nan # 默认会忽略NaN所在组 normal_group data_with_nan.groupby(地区)[销售额].sum() # 包含NaN的组 inclusive_group data_with_nan.groupby(地区, dropnaFalse)[销售额].sum()5. 20个业务场景代码示例区域销售对比分析region_comparison data.groupby(地区).agg( 总销售额(销售额, sum), 平均订单额(销售额, mean), 订单数(订单ID, count) )产品畅销度排名product_rank data.groupby(产品)[数量].sum().sort_values(ascendingFalse)时段销售趋势分析data[小时] pd.to_datetime(data[订单时间]).dt.hour hourly_sales data.groupby(小时)[销售额].sum()用户复购率计算user_repurchase data.groupby(用户ID).agg( 首次购买(订单日期, min), 末次购买(订单日期, max), 购买次数(订单ID, count) )交叉销售机会发现product_pairs data.groupby([用户ID, 产品])[订单ID].count().unstack().fillna(0)价格带销售分析data[价格带] pd.cut(data[单价], bins[0, 100, 300, 500, 1000, float(inf)]) price_segment data.groupby(价格带)[销售额].sum()新老客户对比data[客户类型] np.where(data[注册日期] 2023-01-01, 新客户, 老客户) customer_type data.groupby(客户类型).agg( 人数(用户ID, nunique), 人均消费(销售额, mean) )促销活动效果评估campaign_result data.groupby([活动名称, 地区]).agg( 销售额增长(销售额, sum), 客单价变化(销售额, mean) )库存周转分析inventory_turnover data.groupby(产品).agg( 销售总量(数量, sum), 周转天数(库存天数, mean) )用户生命周期价值ltv data.groupby(用户ID).agg( 总消费(销售额, sum), 活跃天数(订单日期, lambda x: (x.max() - x.min()).days) )渠道质量评估channel_quality data.groupby(流量来源).agg( 转化率(是否成交, mean), 客单价(订单金额, mean) )购物篮分析basket_analysis data.groupby(订单ID)[产品].apply(list).value_counts()退货率监控return_rate data.groupby(产品).agg( 销售数量(数量, sum), 退货数量(退货数量, sum) ) return_rate[退货率] return_rate[退货数量] / return_rate[销售数量]用户留存分析cohort_data data.groupby([注册月份, 订单月份]).agg( 用户数(用户ID, nunique) ).unstack()配送时效分析delivery_time data.groupby(配送中心).agg( 平均时效(配送天数, mean), 准时率(是否准时, mean) )优惠券使用分析coupon_effect data.groupby(是否使用优惠券).agg( 订单数(订单ID, count), 平均金额(订单金额, mean) )客户满意度关联分析satisfaction_corr data.groupby(产品).agg( 销售额(订单金额, sum), 平均评分(满意度评分, mean) )季节性销售模式seasonal_pattern data.groupby([产品, 月份]).agg( 销售额(订单金额, sum) ).unstack().plot()用户行为路径分析user_journey data.sort_values(访问时间).groupby(用户ID)[页面类型].apply(list)RFM用户分群rfm data.groupby(用户ID).agg( 最近购买(订单日期, max), 购买频次(订单ID, count), 消费总额(订单金额, sum) )

更多文章