Harmonic Mean
The harmonic mean is the reciprocal of the arithmetic mean of reciprocals. It is the appropriate average when combining rates, speeds, or ratios where the denominator is the common reference.
The Classic Speed Problem
You drive 100 km at 60 km/h, then 100 km at 40 km/h. What is your average speed?
- Naive arithmetic mean: (60 + 40)/2 = 50 km/h → WRONG
- Correct (harmonic mean): 2/(1/60 + 1/40) = 48 km/h
import numpy as np
from scipy.stats import hmean
import pandas as pd
# ==========================================
# Example 1: Average speed
# ==========================================
speeds = [60, 40] # km/h for equal distances
# Arithmetic mean (wrong!)
arith_speed = np.mean(speeds)
# Harmonic mean (correct for equal distances)
harm_speed = hmean(speeds)
# Verify directly
time_leg1 = 100 / 60 # hours
time_leg2 = 100 / 40 # hours
total_distance = 200 # km
total_time = time_leg1 + time_leg2
actual_avg_speed = total_distance / total_time
print(f"Speed leg 1: {speeds[0]} km/h, Speed leg 2: {speeds[1]} km/h")
print(f"Arithmetic mean: {arith_speed:.4f} km/h ← WRONG")
print(f"Harmonic mean: {harm_speed:.4f} km/h ← CORRECT")
print(f"Calculated directly: {actual_avg_speed:.4f} km/h ✓")
# ==========================================
# Example 2: P/E Ratios in Finance
# ==========================================
# For equal-dollar investments, harmonic mean of P/E ratios
pe_ratios = [20, 25, 15, 30, 10]
portfolio_pe_harm = hmean(pe_ratios)
portfolio_pe_arith = np.mean(pe_ratios)
print(f"\nP/E Ratios: {pe_ratios}")
print(f"Arithmetic mean P/E: {portfolio_pe_arith:.2f}")
print(f"Harmonic mean P/E: {portfolio_pe_harm:.2f}")
print("(Harmonic mean is correct for equal-dollar portfolio weighting)")
# ==========================================
# Example 3: F1-Score in Machine Learning
# ==========================================
# F1 = harmonic mean of Precision and Recall
precision = 0.80
recall = 0.60
f1_hmean = hmean([precision, recall])
f1_formula = 2 * precision * recall / (precision + recall)
arith_mean = np.mean([precision, recall])
print(f"\nPrecision: {precision:.2f}, Recall: {recall:.2f}")
print(f"Arithmetic mean: {arith_mean:.4f}")
print(f"F1 Score (harmonic mean): {f1_hmean:.4f}")
print(f"F1 via standard formula: {f1_formula:.4f}")
print("F1 score punishes large imbalances between P and R!")
Relationship: AM ≥ GM ≥ HM
For any positive values, the three Pythagorean means satisfy:
with equality only when all values are identical.
np.random.seed(42)
for trial in range(5):
x = np.random.uniform(1, 50, 8)
am = np.mean(x)
gm = np.exp(np.log(x).mean())
hm = hmean(x)
print(f"AM={am:.3f} ≥ GM={gm:.3f} ≥ HM={hm:.3f}: {am >= gm >= hm}")
When Each Mean Is Appropriate
| Mean | Formula | Use When |
|---|---|---|
| Arithmetic | Σxᵢ/n | Additive quantities (prices, temperatures) |
| Geometric | (∏xᵢ)^(1/n) | Multiplicative quantities (growth rates, ratios) |
| Harmonic | n/Σ(1/xᵢ) | Rates when denominator is fixed (speed, price per unit) |
Key Takeaways
- Harmonic mean is for rates where the denominator quantity is equal (distance, money)
- F1-score is the harmonic mean of precision and recall in machine learning
- AM ≥ GM ≥ HM always — harmonic mean is smallest, arithmetic is largest
- Never use arithmetic mean for speeds over equal distances — it overestimates
- For unequal distances/time, use a weighted harmonic mean
- Undefined if any value is zero (you can't take 1/0)