拿到一列数值时,直接计算平均值往往不够。极端值可能拉高均值,缺失值可能影响计算,而一张分布图有时比十个统计量更容易暴露问题。描述性统计的任务不是预测未来,而是先把手头的数据讲清楚。
中心在哪里,数据散得有多开
均值适合概括整体水平,但对极端值敏感;中位数表示排序后的中间位置,通常更适合与均值一起看。众数能指出重复出现的值,但连续型数据可能没有特别有意义的众数。
离散程度同样重要:最小值和最大值给出范围,四分位数刻画中间一半数据的位置,标准差反映数据围绕均值的波动。计算标准差时要明确口径:把数据视为总体,还是视为从更大总体抽取的样本。NumPy 中计算样本标准差需要设置 ddof=1。
一段脚本串起五个工具
下面是一份可以直接运行的小例子。先安装依赖,再把脚本保存为 describe_data.py。示例中的 80 是刻意放入的较大观测值;换成自己的数据时,请先确认它是真实记录还是录入错误。
python -m pip install numpy scipy pandas matplotlib
python describe_data.py
# describe_data.py
import statistics
import matplotlib
matplotlib.use("Agg") # 无桌面环境也能保存图片
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from scipy import stats
values = [12, 15, 15, 18, 20, 22, 24, 25, 27, 80]
a = np.asarray(values, dtype=float)
series = pd.Series(a, name="value")
print("均值:", statistics.mean(values))
print("中位数:", statistics.median(values))
print("众数:", statistics.multimode(values))
print("样本标准差:", np.std(a, ddof=1))
print("四分位数:", np.percentile(a, [25, 50, 75]))
print("偏度:", stats.skew(a, bias=False))
print("pandas 汇总:\n", series.describe())
plt.hist(a, bins=[10, 20, 30, 40, 50, 60, 70, 80, 90], edgecolor="black")
plt.xlabel("Value")
plt.ylabel("Count")
plt.title("Value distribution")
plt.tight_layout()
plt.savefig("distribution.png")
print("已保存 distribution.png")
内置 statistics 库适合快速处理普通 Python 数值列表;NumPy 方便做数组运算和分位数计算;pandas 的 describe() 能快速给出计数、均值、标准差和分位数;SciPy 可补充偏度等统计量;Matplotlib 则把分布保存成图片。脚本同时使用这些工具是为了展示各自的用途,实际项目不必为一个均值引入全部依赖。
读数字,也要读图
运行后,对照均值与中位数,再打开 distribution.png。如果两者相差明显,图中又有远离主体的柱子,就值得检查极端值。偏度可以提供分布不对称的线索,但在这种小样本里,不宜只凭一个偏度数值下结论。
把脚本改用于真实数据时,还要先处理空值。pandas.Series.describe() 默认跳过缺失值,而直接传入含有 NaN 的 NumPy 数组可能得到不同结果。建议先报告原始记录数和缺失数,再决定删除、填补还是单独分析缺失记录;不要让不同工具在不知不觉中统计了不同的数据集合。
交付统计结果前检查什么
一份可靠的描述性统计至少应说明数据量、缺失值处理方式,以及标准差使用的是样本还是总体口径。呈现结果时,把均值和中位数并列,配上分位数与分布图;遇到异常值,先核对来源,不要为了让数字好看就删除。这样得到的不是一串孤立指标,而是一份能够被别人复核的数据画像。