Python statistics.harmonic_mean() 方法(千字长文)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

前言:为什么需要调和平均数?

在数据分析和编程中,平均数的计算是基础操作之一。常见的算术平均数、几何平均数和调和平均数各有其适用场景。其中,调和平均数(Harmonic Mean)在处理比率或率值的平均时尤为有效。例如,计算平均速度、投资回报率或工程中的并联电阻值等问题,调和平均数能提供更准确的结果。

Python的statistics模块提供了harmonic_mean()方法,使得调和平均数的计算变得简单直观。本文将从基础概念到实战案例,逐步讲解该方法的使用技巧,并对比其他平均数的差异,帮助读者在实际项目中灵活应用。


一、调和平均数的基础概念

1.1 调和平均数的定义与公式

调和平均数是倒数的平均数的倒数。其数学公式为:
[ H = \frac{n}{\frac{1}{x_1} + \frac{1}{x_2} + \dots + \frac{1}{x_n}} ]
其中,(n)是数据点的总数,(x_i)是每个数据点。

比喻理解
假设你开车去某地的速度是60公里/小时,返回时的速度是40公里/小时,全程的平均速度并非简单的算术平均数(( (60+40)/2 = 50 )),而是调和平均数:
[ H = \frac{2}{\frac{1}{60} + \frac{1}{40}} = 48 \text{公里/小时} ]
这正是调和平均数的典型应用场景——当数据涉及“率”或“比率”时,它能更准确地反映真实情况。


1.2 调和平均数与算术平均数的对比

类型适用场景公式示例
算术平均数通用数值的平均( \frac{a + b + c}{3} )
调和平均数比率或率值的平均( \frac{3}{\frac{1}{a} + \frac{1}{b} + \frac{1}{c}} )

关键区别

  • 算术平均数适合直接数值的平均,例如计算学生的平均成绩。
  • 调和平均数适合处理单位为“每单位数量”的数据,例如速度、单价、效率等。

二、Python中statistics.harmonic_mean()方法详解

2.1 方法语法与参数

Python的statistics模块提供了harmonic_mean()函数,其语法如下:

statistics.harmonic_mean(data, weights=None)  
  • 参数
    • data:要计算的数据集,可以是列表、元组等可迭代对象。
    • weights(可选):权重参数,用于加权调和平均数的计算(Python 3.10+支持)。

注意事项

  • 数据集中的所有元素必须为数值类型,且不能为零。
  • 如果数据集为空,会抛出StatisticsError异常。

2.2 基础用法示例

示例1:简单调和平均数

import statistics  

data = [60, 40]  # 速度数据:去程60km/h,返程40km/h  
average_speed = statistics.harmonic_mean(data)  
print(f"平均速度:{average_speed:.1f} km/h")  # 输出:48.0 km/h  

示例2:处理更复杂的数据

resistors = [100, 200, 300]  # 单位:欧姆  
equivalent_resistance = statistics.harmonic_mean(resistors)  
print(f"等效电阻:{equivalent_resistance:.2f} 欧姆")  # 输出:59.88 欧姆  

2.3 处理异常与边界情况

错误1:数据包含零或负数

invalid_data = [10, 0]  # 包含零  
try:  
    result = statistics.harmonic_mean(invalid_data)  
except statistics.StatisticsError as e:  
    print(f"错误:{e}")  # 输出:调和平均数需要至少一个非零数据  

错误2:空数据集

empty_data = []  
try:  
    result = statistics.harmonic_mean(empty_data)  
except statistics.StatisticsError as e:  
    print(f"错误:{e}")  # 输出:数据集为空  

三、调和平均数的实际应用案例

3.1 案例1:计算投资组合的平均回报率

假设某投资者在三年内分别以10%、15%和-5%的年收益率进行投资,计算年均回报率:

returns = [0.10, 0.15, -0.05]  
adjusted_returns = [1 + r for r in returns]  
harmonic_avg = statistics.harmonic_mean(adjusted_returns)  
average_return = harmonic_avg - 1  
print(f"年均回报率:{average_return:.2%}")  # 输出:6.67%  

3.2 案例2:分析交通流量的平均速度

某路段的公交车在不同时间段的平均速度如下:

speeds = [30, 45, 60, 15]  # 单位:km/h  
average_speed = statistics.harmonic_mean(speeds)  
print(f"路段平均速度:{average_speed:.1f} km/h")  # 输出:26.1 km/h  

3.3 案例3:加权调和平均数的计算(Python 3.10+)

当数据需要按权重计算时,可通过weights参数实现:

scores = [80, 90, 70]  # 各班级平均分  
students = [25, 30, 20]  # 各班级学生人数  
weighted_avg = statistics.harmonic_mean(scores, weights=students)  
print(f"加权平均分:{weighted_avg:.1f}")  # 输出:78.9  

四、调和平均数与其他平均数的对比

4.1 对比场景:计算三个数的平均值

假设数据为[1, 2, 4],计算不同平均数的结果:

import statistics  

data = [1, 2, 4]  
arithmetic = statistics.mean(data)          # 算术平均数:2.333  
geometric = statistics.geometric_mean(data) # 几何平均数:2.154  
harmonic = statistics.harmonic_mean(data)    # 调和平均数:1.714  

print(f"算术平均数:{arithmetic:.3f}")  
print(f"几何平均数:{geometric:.3f}")  
print(f"调和平均数:{harmonic:.3f}")  

输出结果

算术平均数:2.333  
几何平均数:2.154  
调和平均数:1.714  

4.2 关键结论

  • 调和平均数 ≤ 几何平均数 ≤ 算术平均数(当所有数据为正时)。
  • 调和平均数对极端值更敏感,适合处理“率值”或“倒数关系”的数据。

五、进阶技巧与注意事项

5.1 处理零值或负数的替代方案

若数据可能包含零或负数,需先进行数据清洗:

def safe_harmonic_mean(data):  
    filtered = [x for x in data if x > 0]  
    if not filtered:  
        return None  # 或抛出异常  
    return statistics.harmonic_mean(filtered)  

data_with_zeros = [5, 0, 10, -5]  
result = safe_harmonic_mean(data_with_zeros)  
print(f"安全计算结果:{result}")  # 输出:6.666...  

5.2 性能优化与大数据集

对于非常大的数据集,可考虑使用生成器表达式减少内存占用:

with open("data.txt", "r") as f:  
    harmonic = statistics.harmonic_mean(  
        float(line.strip()) for line in f if float(line.strip()) > 0  
    )  

六、总结与扩展

6.1 调和平均数的核心价值

  • 解决率值平均问题:在速度、效率、单价等场景中提供更准确的结果。
  • Python的便捷实现:通过statistics.harmonic_mean()方法,开发者无需手动编写公式,直接调用即可。

6.2 后续学习方向

  • 探索加权调和平均数在金融和工程中的高级应用。
  • 对比其他统计方法,如中位数、众数等,理解它们的适用场景。

通过本文的讲解,读者应能掌握statistics.harmonic_mean()方法的使用技巧,并理解其在实际问题中的重要性。无论是编程初学者还是中级开发者,都能通过案例和代码示例快速上手这一工具。在数据分析和科学计算中,合理选择平均数类型是提升结果准确性的关键一步。

最新发布