一、库的简介:让数据说话的基础工具
你是否曾经需要快速计算班级考试的平均分,却不想手动一个一个加总?或者你想知道某个月的销售额波动有多大,是平稳上升还是时高时低?又或者你在比较两款手机的用户评分,想判断哪一款更受稳定好评?这些日常数据分析场景,都离不开描述性统计中的均值、中位数、方差、标准差等基础概念。Python 的 statistics 标准库正是为此而生------它提供了一系列专门用于数值数据统计的函数,包括均值(mean)、中位数(median)、众数(mode)、方差(variance)、标准差(stdev)等。与 NumPy 等重型科学计算库相比,statistics 更轻量、无需额外安装、API 简洁直观,非常适合在普通 Python 程序中对小到中型数据集进行快速统计分析和质量检查。无论是在校学生分析实验数据,还是产品经理评估用户满意度,亦或是运维人员监控服务器响应时间,statistics 都能让你用最少的代码获得最可靠的统计指标。
二、安装 statistics
statistics 是 Python 3.4 及以上版本的标准库模块,随 Python 解释器一同安装,无需 pip install。你只需要在代码中导入即可:
python
import statistics
可以通过查看版本或调用任意函数来验证是否正常:
python
print(statistics.__doc__) # 查看模块说明
三、基本用法
以下所有示例假设已执行 import statistics。
第一步:计算算术平均数(均值)
statistics.mean(data) 返回数据集的算术平均值,数据必须为非空序列或可迭代对象。
python
scores = [85, 90, 78, 92, 88]
avg = statistics.mean(scores)
print(f"平均分: {avg:.2f}") # 输出: 平均分: 86.60
第二步:计算中位数(消除极端值影响)
中位数是将数据排序后位于中间的值,对于偏态分布或存在异常值的数据,中位数比均值更稳健。
python
# 奇数个元素
data_odd = [3, 5, 1, 7, 9]
print(statistics.median(data_odd)) # 排序后 [1,3,5,7,9] -> 5
# 偶数个元素返回中间两个数的平均值
data_even = [10, 20, 30, 40]
print(statistics.median(data_even)) # (20+30)/2 = 25
# 如果需要总是返回低中位数或高中位数,可使用 median_low / median_high
第三步:计算众数(出现频率最高的值)
statistics.mode 返回出现次数最多的一个值(若多个众数则返回第一个遇到的)。multimode 返回所有众数的列表。
python
colors = ['红', '蓝', '红', '绿', '红', '蓝']
print(statistics.mode(colors)) # '红'
print(statistics.multimode(colors)) # ['红', '蓝']
第四步:计算方差与标准差(衡量数据的离散程度)
-
总体方差 :
pvariance(data)------ 数据代表整个总体 -
样本方差 :
variance(data)------ 数据是总体的一部分(通常用于推断总体) -
标准差 :
pstdev(总体)和stdev(样本),即方差的平方根
python
measurements = [2.3, 2.5, 2.4, 2.6, 2.8]
sample_var = statistics.variance(measurements) # 样本方差
sample_std = statistics.stdev(measurements) # 样本标准差
print(f"样本标准差: {sample_std:.3f}") # 约 0.187
四、高级用法
1. 处理缺失值或无效数据
statistics 函数不接受包含 NaN 或非数值数据的序列,需要先过滤。通常结合列表推导式或 math.isnan 进行清洗。
python
import math
data = [1.2, float('nan'), 2.3, 3.1]
clean = [x for x in data if not math.isnan(x)]
print(statistics.mean(clean)) # (1.2+2.3+3.1)/3 = 2.2
2. 分位数(Quantiles)
statistics.quantiles(data, n=4) 将数据分成 n 个等份,返回 n-1 个分割点。例如 n=4 得到三个四分位数。
python
scores = [55, 62, 68, 72, 75, 79, 82, 85, 90, 95]
q1, median, q3 = statistics.quantiles(scores, n=4)
print(f"Q1={q1}, Median={median}, Q3={q3}") # Q1=68.0, Median=77.0, Q3=85.0
该函数默认使用"排位法"(方法为 'exclusive'),适合样本分位数估计。
3. 几何平均数与调和平均数
-
几何平均 :
geometric_mean(data)------ 常用于增长率、比例数据的平均 -
调和平均 :
harmonic_mean(data)------ 适用于速率、比率的平均,如平均速度
python
growth_rates = [1.05, 1.08, 1.02, 1.10] # 年增长率
geo_mean = statistics.geometric_mean(growth_rates)
print(f"年均增长率: {(geo_mean - 1)*100:.2f}%")
speeds = [60, 50, 75] # 三段路程的速度(km/h)
avg_speed = statistics.harmonic_mean(speeds) # 3/(1/60+1/50+1/75) ≈ 59.5
五、实际应用场景案例
场景一:学生成绩分析报告(含异常检测)
假设老师有一个班级的学生成绩,需要输出平均分、中等水平、成绩稳定性以及是否存在成绩落后过多或异常高的学生(基于 Z-score)。
python
import statistics
def grade_analysis(grades):
"""输出班级成绩统计报告并标出异常成绩"""
mean_val = statistics.mean(grades)
median_val = statistics.median(grades)
stdev_val = statistics.stdev(grades)
print(f"平均分: {mean_val:.2f}")
print(f"中位数: {median_val:.2f}")
print(f"标准差: {stdev_val:.2f}")
# 使用 2 倍标准差作为异常阈值
lower_bound = mean_val - 2 * stdev_val
upper_bound = mean_val + 2 * stdev_val
outliers = [g for g in grades if g < lower_bound or g > upper_bound]
if outliers:
print(f"疑似异常成绩: {outliers}")
else:
print("无显著异常成绩")
# 计算成绩分布的偏态倾向(简单的比较均值和中位数)
if mean_val > median_val:
print("成绩分布右偏(存在高分拖拽均值)")
elif mean_val < median_val:
print("成绩分布左偏(存在低分拖拽均值)")
else:
print("成绩分布基本对称")
# 示例数据
scores = [78, 82, 85, 88, 90, 92, 95, 98, 100, 42] # 42分可能为异常
grade_analysis(scores)
场景二:股票收益率波动性分析
小投资者可以用 statistics 快速评估一只股票日收益率的标准差(波动率)和平均收益,辅助决策。
python
import statistics
def stock_volatility(daily_returns):
"""
输入每日收益率列表(百分比形式,如 [0.5, -0.3, 1.2] 表示 +0.5%, -0.3%, +1.2%)
输出平均收益率、标准差、年化波动率(假设 252 个交易日)
"""
avg_ret = statistics.mean(daily_returns)
vol_daily = statistics.stdev(daily_returns) # 日波动率
annual_vol = vol_daily * (252 ** 0.5) # 年化波动率
print(f"日均收益率: {avg_ret:.4f}%")
print(f"日收益率标准差: {vol_daily:.4f}%")
print(f"年化波动率: {annual_vol:.2f}%")
return vol_daily
# 模拟某股票过去 20 个交易日的收益率(%)
returns = [0.2, -0.5, 1.0, -0.2, 0.8, -1.2, 0.5, 0.3, -0.1, 0.6,
-0.4, 0.9, -0.7, 0.4, -0.3, 0.7, 0.1, -0.6, 0.5, -0.2]
stock_volatility(returns)
场景三:电商商品评分稳定性对比
两个商品的用户评分列表,均值相同但方差不同:一个评分稳定(方差小),另一个忽高忽低(方差大)。通过标准差比较热度真实性。
python
product_a = [4, 5, 4, 5, 4, 5, 4, 5] # 稳定好评
product_b = [1, 5, 3, 5, 2, 5, 4, 3] # 波动大
def compare_ratings(product_a, product_b):
mean_a = statistics.mean(product_a)
mean_b = statistics.mean(product_b)
std_a = statistics.stdev(product_a)
std_b = statistics.stdev(product_b)
print(f"商品A: 平均{mean_a:.2f}, 标准差{std_a:.2f}")
print(f"商品B: 平均{mean_b:.2f}, 标准差{std_b:.2f}")
if std_a < std_b:
print("商品A的用户评价更一致,推荐度更可信")
else:
print("商品B的用户评价分歧较大,需关注差评原因")
compare_ratings(product_a, product_b)
六、结尾互动
statistics 模块是 Python 标准库中被低估的宝藏之一。它让数据科学家之外的普通开发者也能轻松驾驭基础的统计分析,而不必立即引入庞大的 NumPy 或 Pandas。从班级成绩到股市波动,从产品评分到传感器数据质量监控,statistics 总能以最轻量的方式帮你看清数据的全貌。更重要的是,理解均值、中位数、标准差这些统计量,能让你在面对"平均工资""平均房价"等社会统计数据时,多一分批判性思考------因为它们可能掩盖了真实分布的不平等。
如果你曾用 statistics 做过数据分析,或者遇到过让你困惑的平均值陷阱,欢迎在评论区分享。你还可以尝试用 statistics.quantiles 来绘制一个简单的箱线图(配合 matplotlib),看看异常值的分布。期待你的实践活动!