统计分析 #
统计分析概述 #
Pandas 提供了丰富的统计分析功能,可以快速了解数据的分布特征和变量关系。
text
┌─────────────────────────────────────────────────────────────┐
│ 统计分析方法 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 描述统计 │
│ ├── 集中趋势:mean, median, mode │
│ ├── 离散程度:std, var, range │
│ └── 分布形状:skew, kurt │
│ │
│ 相关性分析 │
│ ├── 相关系数:corr │
│ └── 协方差:cov │
│ │
│ 分组统计 │
│ ├── groupby │
│ └── pivot_table │
│ │
│ 假设检验 │
│ └── scipy.stats │
│ │
└─────────────────────────────────────────────────────────────┘
准备数据 #
python
import pandas as pd
import numpy as np
np.random.seed(42)
df = pd.DataFrame({
'category': np.random.choice(['A', 'B', 'C'], 100),
'value1': np.random.normal(100, 15, 100),
'value2': np.random.normal(50, 10, 100),
'value3': np.random.normal(0, 1, 100) * 100 + np.random.normal(100, 15, 100)
})
df['value3'] = df['value1'] + np.random.normal(0, 5, 100) # 与 value1 相关
描述统计 #
基本统计方法 #
python
# 均值
print(df['value1'].mean())
# 中位数
print(df['value1'].median())
# 众数
print(df['category'].mode())
# 标准差
print(df['value1'].std())
# 方差
print(df['value1'].var())
# 最小值
print(df['value1'].min())
# 最大值
print(df['value1'].max())
# 范围
print(df['value1'].max() - df['value1'].min())
# 分位数
print(df['value1'].quantile([0.25, 0.5, 0.75]))
describe 方法 #
python
# 数值列统计
print(df.describe())
# 所有列统计
print(df.describe(include='all'))
# 自定义百分位数
print(df.describe(percentiles=[0.1, 0.5, 0.9]))
# 只统计对象类型
print(df.describe(include=['object']))
# 只统计数值类型
print(df.describe(include=['number']))
集中趋势 #
python
# 均值
print(df.mean(numeric_only=True))
# 中位数
print(df.median(numeric_only=True))
# 众数
print(df.mode())
# 加权平均
weights = np.random.rand(100)
print(np.average(df['value1'], weights=weights))
离散程度 #
python
# 标准差
print(df.std(numeric_only=True))
# 方差
print(df.var(numeric_only=True))
# 极差
print(df.max(numeric_only=True) - df.min(numeric_only=True))
# 四分位距(IQR)
Q1 = df.quantile(0.25, numeric_only=True)
Q3 = df.quantile(0.75, numeric_only=True)
IQR = Q3 - Q1
print(IQR)
# 变异系数
cv = df.std(numeric_only=True) / df.mean(numeric_only=True)
print(cv)
分布形状 #
python
# 偏度
print(df.skew(numeric_only=True))
# 正偏态(>0):右尾较长
# 负偏态(<0):左尾较长
# 峰度
print(df.kurtosis(numeric_only=True))
# 正峰度(>0):比正态分布更尖
# 负峰度(<0):比正态分布更平
累计统计 #
python
# 累计求和
print(df['value1'].cumsum())
# 累计乘积
print(df['value1'].cumprod())
# 累计最大值
print(df['value1'].cummax())
# 累计最小值
print(df['value1'].cummin())
计数统计 #
python
# 非空值计数
print(df.count())
# 唯一值计数
print(df['category'].nunique())
# 值计数
print(df['category'].value_counts())
# 值计数(比例)
print(df['category'].value_counts(normalize=True))
相关性分析 #
相关系数 #
python
# Pearson 相关系数(默认)
print(df[['value1', 'value2', 'value3']].corr())
# Spearman 相关系数
print(df[['value1', 'value2', 'value3']].corr(method='spearman'))
# Kendall 相关系数
print(df[['value1', 'value2', 'value3']].corr(method='kendall'))
# 单列相关性
print(df.corrwith(df['value1'], numeric_only=True))
协方差 #
python
# 协方差矩阵
print(df[['value1', 'value2', 'value3']].cov())
# 单列协方差
print(df['value1'].cov(df['value3']))
相关性可视化 #
python
import matplotlib.pyplot as plt
import seaborn as sns
# 相关性热力图
plt.figure(figsize=(8, 6))
sns.heatmap(df[['value1', 'value2', 'value3']].corr(),
annot=True, cmap='coolwarm', center=0)
plt.title('Correlation Heatmap')
plt.show()
# 散点图矩阵
pd.plotting.scatter_matrix(df[['value1', 'value2', 'value3']],
figsize=(10, 8))
plt.show()
分组统计 #
基本分组 #
python
# 单列分组
print(df.groupby('category')['value1'].mean())
# 多列分组
print(df.groupby('category')[['value1', 'value2']].mean())
# 多个聚合函数
print(df.groupby('category')['value1'].agg(['mean', 'std', 'count']))
# 自定义聚合
print(df.groupby('category').agg({
'value1': ['mean', 'std'],
'value2': ['min', 'max'],
'category': 'count'
}))
多级分组 #
python
# 添加分组列
df['group'] = np.random.choice(['X', 'Y'], 100)
# 多级分组
print(df.groupby(['category', 'group'])['value1'].mean())
# 分组后多列聚合
print(df.groupby(['category', 'group']).agg({
'value1': 'mean',
'value2': 'std'
}))
分组转换 #
python
# 标准化
df['value1_std'] = df.groupby('category')['value1'].transform(
lambda x: (x - x.mean()) / x.std()
)
# 填充缺失值
df['value1_filled'] = df.groupby('category')['value1'].transform(
lambda x: x.fillna(x.mean())
)
# 排名
df['rank'] = df.groupby('category')['value1'].rank()
分组过滤 #
python
# 过滤分组
print(df.groupby('category').filter(lambda x: x['value1'].mean() > 100))
# 过滤后保留原索引
print(df.groupby('category').filter(lambda x: len(x) > 30))
透视表 #
创建透视表 #
python
# 基本透视表
print(pd.pivot_table(df, values='value1', index='category', aggfunc='mean'))
# 多值
print(pd.pivot_table(df,
values=['value1', 'value2'],
index='category',
aggfunc='mean'))
# 多索引
print(pd.pivot_table(df,
values='value1',
index=['category', 'group'],
aggfunc='mean'))
# 多列
print(pd.pivot_table(df,
values='value1',
index='category',
columns='group',
aggfunc='mean'))
# 多聚合函数
print(pd.pivot_table(df,
values='value1',
index='category',
aggfunc=['mean', 'std', 'count']))
交叉表 #
python
# 频数表
print(pd.crosstab(df['category'], df['group']))
# 带边际汇总
print(pd.crosstab(df['category'], df['group'], margins=True))
# 归一化
print(pd.crosstab(df['category'], df['group'], normalize='all'))
# 带值聚合
print(pd.crosstab(df['category'], df['group'],
values=df['value1'], aggfunc='mean'))
假设检验 #
正态性检验 #
python
from scipy import stats
# Shapiro-Wilk 检验
stat, p = stats.shapiro(df['value1'])
print(f'Statistic: {stat}, p-value: {p}')
if p > 0.05:
print('数据可能服从正态分布')
else:
print('数据可能不服从正态分布')
# Kolmogorov-Smirnov 检验
stat, p = stats.kstest(df['value1'], 'norm')
print(f'Statistic: {stat}, p-value: {p}')
t 检验 #
python
# 单样本 t 检验
stat, p = stats.ttest_1samp(df['value1'], 100)
print(f't-statistic: {stat}, p-value: {p}')
# 独立样本 t 检验
group_a = df[df['category'] == 'A']['value1']
group_b = df[df['category'] == 'B']['value1']
stat, p = stats.ttest_ind(group_a, group_b)
print(f't-statistic: {stat}, p-value: {p}')
# 配对样本 t 检验
stat, p = stats.ttest_rel(df['value1'], df['value3'])
print(f't-statistic: {stat}, p-value: {p}')
方差分析(ANOVA) #
python
# 单因素方差分析
groups = [df[df['category'] == cat]['value1'] for cat in df['category'].unique()]
stat, p = stats.f_oneway(*groups)
print(f'F-statistic: {stat}, p-value: {p}')
相关性检验 #
python
# Pearson 相关性检验
corr, p = stats.pearsonr(df['value1'], df['value3'])
print(f'Correlation: {corr}, p-value: {p}')
# Spearman 相关性检验
corr, p = stats.spearmanr(df['value1'], df['value3'])
print(f'Correlation: {corr}, p-value: {p}')
卡方检验 #
python
# 卡方独立性检验
contingency_table = pd.crosstab(df['category'], df['group'])
chi2, p, dof, expected = stats.chi2_contingency(contingency_table)
print(f'Chi-square: {chi2}, p-value: {p}')
统计报告 #
python
def statistical_report(df, column):
print(f"\n{'='*50}")
print(f"统计报告: {column}")
print(f"{'='*50}")
data = df[column]
print(f"\n基本统计:")
print(f" 样本量: {len(data)}")
print(f" 缺失值: {data.isna().sum()}")
print(f" 均值: {data.mean():.2f}")
print(f" 中位数: {data.median():.2f}")
print(f" 标准差: {data.std():.2f}")
print(f" 最小值: {data.min():.2f}")
print(f" 最大值: {data.max():.2f}")
print(f"\n分位数:")
for q in [0.25, 0.5, 0.75]:
print(f" {int(q*100)}%: {data.quantile(q):.2f}")
print(f"\n分布形状:")
print(f" 偏度: {data.skew():.2f}")
print(f" 峰度: {data.kurtosis():.2f}")
stat, p = stats.shapiro(data)
print(f"\n正态性检验 (Shapiro-Wilk):")
print(f" 统计量: {stat:.4f}")
print(f" p-value: {p:.4f}")
print(f" 结论: {'正态分布' if p > 0.05 else '非正态分布'}")
statistical_report(df, 'value1')
下一步 #
掌握了统计分析后,接下来学习 分组聚合,深入了解 Pandas 强大的分组功能!
最后更新:2026-04-04