Skip to content

描述性统计

Descriptive Statistics

描述性统计是数据分析的起点,用于总结和描述数据的基本特征。


目录


核心概念

集中趋势度量

集中趋势度量用于描述数据的"中心位置",回答"典型值是多少"的问题。

均值(Mean)

所有数据的算术平均。

\[ \bar{x} = \frac{1}{n}\sum_{i=1}^{n} x_i \]

特点: - 利用所有数据信息 - 对异常值敏感 - 适用于对称分布

中位数(Median)

将数据排序后位于中间位置的值。

特点: - 对异常值不敏感 - 适用于偏态分布 - 稳健性更好

众数(Mode)

出现频率最高的值。

特点: - 适用于类别数据 - 可能有多个众数 - 不受极端值影响


离散程度度量

离散程度度量用于描述数据的"分散程度",回答"数据波动多大"的问题。

方差(Variance)

各数据与均值差的平方的平均。

\[ s^2 = \frac{1}{n-1}\sum_{i=1}^{n} (x_i - \bar{x})^2 \]

标准差(Standard Deviation)

方差的平方根,与原始数据单位一致。

\[ s = \sqrt{s^2} \]

特点: - 68-95-99.7 法则(正态分布) - 越小表示数据越集中 - 最常用的离散度量

四分位距(IQR)

第三四分位数与第一四分位数的差。

\[ IQR = Q3 - Q1 \]

特点: - 对异常值不敏感 - 用于识别异常值 - 适用于偏态分布


分布形态

偏度(Skewness)

描述分布的对称性。

  • 偏度 = 0: 对称分布
  • 偏度 > 0: 右偏(正偏)
  • 偏度 < 0: 左偏(负偏)

峰度(Kurtosis)

描述分布的"尖锐程度"。

  • 峰度 = 3: 正态分布(常峰态)
  • 峰度 > 3: 尖峰厚尾
  • 峰度 < 3: 低峰薄尾

实践应用

步骤 1: 数据概览

使用描述性统计快速了解数据集的整体特征。

步骤 2: 识别异常值

通过箱线图和 IQR 法则识别潜在的异常值。

步骤 3: 分布判断

通过偏度、峰度和可视化判断数据分布形态。

步骤 4: 组间比较

比较不同组别的统计量,发现差异。


代码示例

示例 1: 计算基本统计量

import pandas as pd
import numpy as np

# 创建示例数据
np.random.seed(42)
data = np.random.normal(loc=100, scale=15, size=1000)
series = pd.Series(data)

# 集中趋势
print(f"均值:{series.mean():.2f}")
print(f"中位数:{series.median():.2f}")
print(f"众数:{series.mode().values[0]:.2f}")

# 离散程度
print(f"方差:{series.var():.2f}")
print(f"标准差:{series.std():.2f}")
print(f"极差:{series.max() - series.min():.2f}")

# 分布形态
print(f"偏度:{series.skew():.2f}")
print(f"峰度:{series.kurtosis():.2f}")

输出说明: - mean() 计算算术平均 - median() 计算中位数 - std() 计算标准差(除以 n-1) - skew() 计算偏度 - kurtosis() 计算峰度

示例 2: 使用 describe() 快速概览

import pandas as pd

# 加载数据
df = pd.read_csv('sales_data.csv')

# 数值型列的描述统计
numeric_summary = df.describe()
print(numeric_summary)

# 分类型列的描述统计
categorical_summary = df.describe(include=['object'])
print(categorical_summary)

describe() 输出包含: - count: 非空值数量 - mean: 均值 - std: 标准差 - min: 最小值 - 25%: 第一四分位数 - 50%: 中位数 - 75%: 第三四分位数 - max: 最大值

示例 3: 识别异常值

import numpy as np

def detect_outliers_iqr(data):
    """使用 IQR 方法识别异常值"""
    Q1 = np.percentile(data, 25)
    Q3 = np.percentile(data, 75)
    IQR = Q3 - Q1

    # 异常值界限
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR

    # 识别异常值
    outliers = [(i, x) for i, x in enumerate(data) 
                if x < lower_bound or x > upper_bound]

    return outliers, lower_bound, upper_bound

# 使用示例
outliers, lower, upper = detect_outliers_iqr(data)
print(f"异常值数量:{len(outliers)}")
print(f"正常范围:[{lower:.2f}, {upper:.2f}]")

常见问题

Q1: 均值和中位数应该用哪个?

A: - 如果数据对称分布,用均值(利用更多信息) - 如果数据有偏态或异常值,用中位数(更稳健) - 收入、房价等通常使用中位数

示例

# 收入数据通常右偏
incomes = [3000, 3500, 4000, 4500, 5000, 5500, 100000]
print(f"均值:{np.mean(incomes):.0f}")     # 17929
print(f"中位数:{np.median(incomes):.0f}")  # 4500

Q2: 为什么样本方差除以 n-1 而不是 n?

A: 这是 Bessel 校正,使样本方差成为总体方差的无偏估计。

Q3: 标准差和标准误有什么区别?

A: - 标准差: 描述数据的离散程度 - 标准误: 描述样本均值的抽样误差

\[ SE = \frac{s}{\sqrt{n}} \]

最佳实践

✅ 推荐做法

# 同时报告多个统计量
def comprehensive_summary(data):
    return {
        '样本量': len(data),
        '均值': data.mean(),
        '中位数': data.median(),
        '标准差': data.std(),
        '最小值': data.min(),
        '最大值': data.max(),
        '偏度': data.skew(),
        '峰度': data.kurtosis()
    }

❌ 避免做法

# 只报告均值,不报告离散程度
# 错误:均值无法反映数据分布全貌

# 对偏态数据只使用均值
# 错误:均值会被极端值拉偏

参考资源

书籍

  • 《统计学图鉴》- 第 2 章
  • 《赤裸裸的统计学》- 第 3 章

文章

工具


下一步学习


最后更新: 2026-06-01