Pandas crosstab隐藏玩法:除了计数,还能这样算占比、求均值,做数据洞察

张开发
2026/5/9 17:40:27 15 分钟阅读

分享文章

Pandas crosstab隐藏玩法:除了计数,还能这样算占比、求均值,做数据洞察
Pandas crosstab隐藏玩法除了计数还能这样算占比、求均值做数据洞察如果你以为pd.crosstab()只能做简单的频数统计那可能错过了这个函数90%的实用价值。在实际数据分析工作中我们经常需要回答这样的问题市场部各绩效等级的平均薪资是多少不同地区商品销售额占总销售额的百分比如何分布这些看似复杂的问题其实用crosstab的进阶参数组合就能轻松解决。1. 重新认识crosstab的核心参数pd.crosstab()的强大之处在于它的参数组合能产生完全不同的分析视角。让我们先拆解三个最容易被低估的参数pd.crosstab( indexdf[部门], # 行分类变量 columnsdf[绩效等级], # 列分类变量 valuesdf[薪资], # 待聚合的数值列 aggfuncmean, # 聚合函数 normalizeindex # 标准化方式 )values参数的加入让分析维度从计数升级为计算。当它与aggfunc配合时可以实现aggfuncmean→ 计算分组平均值aggfuncsum→ 计算分组总和aggfunclambda x: sum(x5000)→ 自定义聚合逻辑而normalize参数则提供了四种标准化方式参数值作用适用场景True整体占比看全局分布index行方向占比分析行内结构columns列方向占比分析列内结构all等同于True兼容旧版本2. 人力资源分析实战绩效与薪资的多维透视假设我们有一份包含员工部门、绩效评级和薪资的数据。传统做法可能先分组再计算其实用crosstab一行代码就能实现import pandas as pd import numpy as np # 示例数据 data { 部门: [技术部]*5 [市场部]*5, 绩效: [A,B,B,C,A, A,C,B,A,C], 薪资: [15000, 12000, 13000, 10000, 16000, 14000, 11000, 12500, 14500, 9000] } df pd.DataFrame(data) # 基础频数统计 print(pd.crosstab(df[部门], df[绩效]))输出是简单的计数交叉表绩效 A B C 部门 市场部 2 1 2 技术部 2 2 1现在加入values和aggfunc# 计算各绩效等级的平均薪资 salary_mean pd.crosstab( indexdf[部门], columnsdf[绩效], valuesdf[薪资], aggfuncmean )得到的结果立即变得更有业务价值绩效 A B C 部门 市场部 14250.0 12500 10000.0 技术部 15500.0 12500 10000.0进一步分析薪资结构占比# 计算各部门内各绩效等级的薪资占比 salary_pct pd.crosstab( indexdf[部门], columnsdf[绩效], valuesdf[薪资], aggfuncsum, normalizeindex )输出结果直观显示各部门薪资成本分布绩效 A B C 部门 市场部 0.40566 0.177305 0.417035 技术部 0.50877 0.228070 0.2631583. 销售分析进阶多维交叉与边际计算对于销售数据我们经常需要分析产品在不同维度的表现。假设有以下数据集sales { 产品: [手机]*6 [平板]*5 [笔记本]*4, 地区: [北京,上海,广州,北京,深圳,成都] [北京,上海,杭州,广州,深圳] [北京,上海,杭州,广州], 销售额: [8000, 7500, 6800, 8200, 7800, 6500, 5500, 5200, 4800, 5300, 5600, 12000, 11500, 10500, 11000] } sales_df pd.DataFrame(sales)场景1计算各产品在不同地区的销售额占比列方向region_pct pd.crosstab( indexsales_df[产品], columnssales_df[地区], valuessales_df[销售额], aggfuncsum, normalizecolumns )场景2带总计的多维分析# 添加边际总计 sales_summary pd.crosstab( indexsales_df[产品], columnssales_df[地区], valuessales_df[销售额], aggfuncsum, marginsTrue, margins_name总计 )输出表格自动计算行列总计地区 北京 上海 杭州 广州 深圳 成都 总计 产品 笔记本 12000 11500 10500 11000 0 0 45000 平板 5500 5200 4800 5300 5600 0 26400 手机 8000 7500 0 6800 7800 6500 36600 总计 25500 24200 15300 23100 13400 6500 1080004. 高级技巧自定义聚合与多层索引当基础聚合函数不能满足需求时可以传入自定义函数# 计算销售额超过7000的交易占比 def high_sales_ratio(x): return (x 7000).mean() pd.crosstab( indexsales_df[产品], columnssales_df[地区], valuessales_df[销售额], aggfunchigh_sales_ratio )对于更复杂的多维分析可以构建多层索引# 添加日期维度 sales_df[季度] [Q1,Q1,Q1,Q2,Q2,Q2] \ [Q1,Q1,Q2,Q2,Q2] \ [Q1,Q2,Q2,Q1] result pd.crosstab( index[sales_df[产品], sales_df[季度]], columnssales_df[地区], valuessales_df[销售额], aggfuncsum )输出结果自动形成层级索引地区 北京 上海 杭州 广州 深圳 成都 产品 季度 笔记本 Q1 12000 0 0 0 0 0 Q2 0 11500 10500 11000 0 0 平板 Q1 5500 5200 0 0 0 0 Q2 0 0 4800 5300 5600 0 手机 Q1 8000 7500 0 6800 0 0 Q2 0 0 0 0 7800 65005. 性能优化与避坑指南虽然crosstab功能强大但在大数据量下需要注意内存优化对于超过100万行的数据考虑先对分类变量进行分桶空值处理默认dropnaTrue会自动过滤含NaN的行列替代方案当需要极高性能时pivot_table()可能是更好的选择# 等效的pivot_table写法 pd.pivot_table( datadf, index部门, columns绩效, values薪资, aggfuncmean )两者主要区别在于特性crosstabpivot_table输入接受Series/数组必须使用DataFrame默认聚合计数均值性能稍快稍慢灵活性参数组合丰富支持多重聚合实际项目中当需要快速探索分类变量关系时我会优先使用crosstab而在构建正式报表时pivot_table的语法往往更易维护。

更多文章