Python案例:如何用Pandas做数据描述统计——从零到实战的完整指南
📖 目录导读
- 数据描述统计是什么?为什么重要?
- Pandas描述统计核心方法速览
- 实战案例1:零售销售数据快速概览
- 实战案例2:处理缺失值与异常值时的统计技巧
- 实战案例3:分组描述统计——按类别、时间、地区
- 数据可视化与描述统计的黄金组合
- 常见问题Q&A(SEO重点段落)
- 用Pandas做描述统计的3个关键心法
数据描述统计是什么?为什么重要?
描述统计(Descriptive Statistics) 是通过图表、数值指标(如均值、中位数、标准差、分位数等)来总结、描述数据分布和集中趋势的方法,它不像推断统计那样要“证明假设”,而是帮助你在分析前快速摸清数据全貌。

举个场景:你拿到一份100万行销售数据,第一眼想知道的不是模型预测,而是“总销售额多少”、“哪些商品利润最高”、“数据是否有缺失或极端值”,这时,Pandas的
describe()、value_counts()、groupby().agg()就是你的快速诊断工具。
为什么必须用Pandas做描述统计?
- 效率:手算会累死,Pandas一行代码输出全部关键指标。
- 可控性:可自由组合函数(均值、中位数、自定义函数)。
- 可扩展:直接与可视化(Matplotlib/Seaborn)对接,生成统计报告。
Pandas描述统计核心方法速览
| 方法 | 功能 | 适用场景 |
|---|---|---|
df.describe() |
输出数值型列:计数、均值、标准差、最小值、25%/50%/75%分位数、最大值 | 快速扫描数值分布 |
df.describe(include='object') |
输出文本列:频数、唯一值数、出现最多的值 | 分类变量概况 |
df['col'].value_counts() |
统计某一列各值出现次数(可带normalize=True算占比) |
类别分布检查 |
df.corr() |
计算数值列间的相关系数矩阵 | 变量相关性初探 |
df['col'].agg(['mean','median','std']) |
自定义聚合多个统计量 | 灵活定制统计指标 |
df.groupby('cat').agg(...) |
分组后做描述统计 | 按类别/时间查看差异 |
实战案例1:零售销售数据快速概览
假设我们有一个电商小数据集 orders.csv,包含 order_id, total_price, quantity, product_category, order_date 几列。
import pandas as pd
import numpy as np
# 加载数据(模拟数据,实际请替换为真实路径)
df = pd.read_csv('orders.csv')
# 1. 看一眼整体
print(df.head()) # 前5行
print(df.info()) # 列类型、非空计数——快速发现缺失值
# 2. 核心描述统计
print(df.describe())
# 输出示例:total_price均值=150.2,std=80.5,min=12.0,max=999.0
# 🌟 一看就发现问题:max=999远高于75%分位数约180,暗示存在异常大单
# 3. 对象列描述
print(df.describe(include='object'))
# product_category的unique=5,最频繁为"电子产品"(占比35%)
# 4. 细分数值分布
total_price = df['total_price']
print(f"偏度: {total_price.skew():.2f}") # >1 代表右偏(有极端高值)
print(f"峰度: {total_price.kurtosis():.2f}") # 高说明尾部有极端值
关键洞察:通过describe()一眼识别出“存在极端高值”——这是后续清洗或分层分析的重要信号。
实战案例2:处理缺失值与异常值时的统计技巧
现实数据的N个坑:缺失值NaN、零值异常、负值异常,描述统计能帮你快速定位。
(1) 缺失值诊断
# 每列缺失数量
print(df.isnull().sum())
# 若total_price有缺失,用描述统计看有值部分是什么分布
valid_price = df['total_price'].dropna()
print(f"有值时均值: {valid_price.mean():.2f},中位数: {valid_price.median():.2f}")
# 思考:均值vs中位数差异大,说明有极端值影响,填充缺失时用中位数更稳健
(2) 异常值初步判定(IQR法)
Q1 = df['total_price'].quantile(0.25)
Q3 = df['total_price'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers = df[(df['total_price'] < lower_bound) | (df['total_price'] > upper_bound)]
print(f"异常值数量: {len(outliers)},占总体 {len(outliers)/len(df)*100:.1f}%")
# 通常异常值若<5%可考虑剔除或截尾;若>10%需排查业务原因
实战案例3:分组描述统计——按类别、时间、地区
按产品类别统计销售额分布
# 分组后分别求均值、中位数、总数
category_stats = df.groupby('product_category')['total_price'].agg(
['mean', 'median', 'sum', 'count', 'std']
).rename(columns={
'mean': '平均销售额',
'median': '中位数销售额',
'sum': '总销售额',
'count': '订单数',
'std': '标准差'
})
print(category_stats.sort_values('总销售额', ascending=False))
按月份统计订单量趋势
df['order_date'] = pd.to_datetime(df['order_date'])
df['month'] = df['order_date'].dt.to_period('M')
monthly_stats = df.groupby('month')['total_price'].agg(['sum','mean','count'])
print(monthly_stats.head())
# 可发现:12月总销售额激增,但均单下降(说明促销低价单多)
商业洞察:中位数与均值差异越大,说明该组数据分布越不均衡(如“电子产品”组有一个超高价订单拉高了均值)。
数据可视化与描述统计的黄金组合
描述统计输出的数字是“骨架”,图表才是“血肉”,Pandas与Matplotlib/Seaborn结合能快速生成可洞察的统计图。
import matplotlib.pyplot as plt
import seaborn as sns
# 直方图 + 统计线 —— 直观展示分布
plt.figure(figsize=(10,5))
sns.histplot(df['total_price'], bins=50, kde=True)
plt.axvline(df['total_price'].mean(), color='red', linestyle='--', label=f'均值:{df["total_price"].mean():.1f}')
plt.axvline(df['total_price'].median(), color='green', linestyle='-', label=f'中位数:{df["total_price"].median():.1f}')
plt.legend()'总价分布:均值 vs 中位数差异说明右偏')
plt.show()
# 箱线图 —— 一目了然的分位数与异常值
sns.boxplot(x='product_category', y='total_price', data=df)'各品类价格箱线图——快速定位异常类别')
plt.show()
为什么这样结合重要? 有一次我只看describe()认为数据正常,但画了直方图发现存在一个长尾分布——80%订单低于100元,但有几个单50万以上,统计数字被平均模糊了,图表让异常显形。
常见问题Q&A(SEO重点段落)
Q1:df.describe()只显示数值列怎么办?
A:加参数include='all'会显示所有列,对于文本列会显示count、unique(唯一值数)、top(出现最多的值)、freq(该值出现次数),这个技巧常被新手忽略,但当你需要快速理解分类变量时非常有用。
Q2:描述统计中,均值和中位数选哪个更准确?
A:取决于分布,如果数据接近正态(比如学生身高),均值更好;如果存在异常值(比如公司薪资,老板工资拉高均值),中位数更代表“普通人水平”,Pandas可以让两者同时输出,方便对比。
Q3:描述统计能否处理时间序列数据?
A:可以但需注意——describe()对日期会输出最早/最晚日期,更专业的做法:用resample()(按日/周/月聚合)后再做统计,比如df.resample('M', on='order_date')['total_price'].agg(['mean','sum'])。
Q4:大数据集(百万行)用Pandas描述统计会不会很慢?
A:会,建议先用df.sample(0.1)抽取10%样本做快速描述;另外避免对全dataframe频繁调用value_counts()(它可能创建巨大Series),使用df['col'].value_counts(ascending=True).head(10)只关注前后10个值。
Q5:描述统计完成后,下一步做什么数据分析?
A:如果发现缺失多→做插补;发现异常值→决定剔除还是保留;发现变量强相关→用于特征选择,描述统计其实是数据清洗和探索性分析(EDA)的起点,不是终点。
用Pandas做描述统计的3个关键心法
- 不要只看均值——同时看中位数和分位数,避免被极端值欺骗,很多时候“平均工资”比“中位数工资”高50%以上,这才是真正的市场真相。
- 分组描述比总体描述更有价值——在业务场景中,“全部订单均值”远不如“华东区电子产品订单均值”来得有用,让统计语言和业务语言对齐。
- 让数字说话,让图表补完——
describe()是体检报告,histplot/boxplot是CT扫描,两者结合,你才不会漏掉数据里的癌症或宝藏。
最后送你一个快速检查清单:拿到数据后,先跑info()看缺失,再跑describe()看极值,然后groupby做分层透视,最后画两个图看一眼分布,这15分钟的工作,能避免后面90%的模型陷阱。
(本文案例代码均可在Jupyter Notebook中直接运行,数据可用pd.DataFrame自行构造模拟,如需真实数据集,推荐Kaggle的“零售销售”数据集进行练习。)