本文目录导读:

- 案例1:单因素方差分析(One-Way ANOVA)
- 案例2:双因素方差分析(Two-Way ANOVA)
- 案例3:重复测量方差分析
- 案例4:可视化分析
- 案例5:事后检验(Post-hoc Analysis)
- 完整分析函数
我来介绍如何使用Pandas进行数据分组方差分析(ANOVA),以下是几个常见案例:
案例1:单因素方差分析(One-Way ANOVA)
示例数据:三种不同教学方法对学生成绩的影响
import pandas as pd
import numpy as np
from scipy import stats
from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm
import matplotlib.pyplot as plt
import seaborn as sns
# 创建示例数据
np.random.seed(42)
# 生成三种教学方法的数据
method_A = np.random.normal(75, 10, 30)
method_B = np.random.normal(80, 10, 30)
method_C = np.random.normal(85, 10, 30)
# 创建DataFrame
df = pd.DataFrame({
'score': np.concatenate([method_A, method_B, method_C]),
'method': ['A']*30 + ['B']*30 + ['C']*30
})
print("数据预览:")
print(df.head(10))
print(f"\n数据集形状:{df.shape}")
方法1:使用scipy进行单因素方差分析
# 分组计算描述性统计
group_stats = df.groupby('method')['score'].describe()
print("各组描述性统计:")
print(group_stats)
# 执行单因素方差分析
group_A = df[df['method'] == 'A']['score']
group_B = df[df['method'] == 'B']['score']
group_C = df[df['method'] == 'C']['score']
f_statistic, p_value = stats.f_oneway(group_A, group_B, group_C)
print(f"\nF统计量: {f_statistic:.4f}")
print(f"P值: {p_value:.6f}")
# 判断结果
alpha = 0.05
if p_value < alpha:
print(f"p值 = {p_value:.4f} < 0.05,拒绝原假设,各组均值存在显著差异")
else:
print(f"p值 = {p_value:.4f} >= 0.05,不能拒绝原假设,各组均值无显著差异")
方法2:使用statsmodels进行详细分析
# 使用OLS模型进行方差分析
model = ols('score ~ C(method)', data=df).fit()
anova_table = anova_lm(model, typ=2)
print("方差分析表:")
print(anova_table)
# 获取模型摘要
print("\n模型摘要:")
print(model.summary())
案例2:双因素方差分析(Two-Way ANOVA)
示例数据:不同肥料和灌溉方式对作物产量的影响
# 创建双因素实验数据
np.random.seed(42)
fertilizers = ['Fert_A', 'Fert_B', 'Fert_C']
irrigations = ['Drip', 'Sprinkler', 'Flood']
data = []
for fert in fertilizers:
for irrig in irrigations:
# 每组生成10个样本
yield_values = np.random.normal(50, 10, 10) + \
(fertilizers.index(fert) * 5) + \
(irrigations.index(irrig) * 3)
for y in yield_values:
data.append({'fertilizer': fert, 'irrigation': irrig, 'yield': y})
df_2way = pd.DataFrame(data)
print("双因素数据预览:")
print(df_2way.head())
print(f"\n数据集形状:{df_2way.shape}")
双因素方差分析
# 执行双因素方差分析
model_2way = ols('yield ~ C(fertilizer) * C(irrigation)', data=df_2way).fit()
anova_2way = anova_lm(model_2way, typ=2)
print("双因素方差分析表:")
print(anova_2way)
# 检查交互效应
print("\n交互效应分析:")
fertilizer_p = anova_2way.loc['C(fertilizer)', 'PR(>F)']
irrigation_p = anova_2way.loc['C(irrigation)', 'PR(>F)']
interaction_p = anova_2way.loc['C(fertilizer):C(irrigation)', 'PR(>F)']
print(f"肥料主效应 p值: {fertilizer_p:.4f}")
print(f"灌溉方式主效应 p值: {irrigation_p:.4f}")
print(f"交互效应 p值: {interaction_p:.4f}")
案例3:重复测量方差分析
# 创建重复测量数据
np.random.seed(42)
# 模拟10个学生在3次考试中的成绩
students = [f'Student_{i}' for i in range(1, 11)]
exams = ['Exam_1', 'Exam_2', 'Exam_3']
data = []
for student in students:
base_score = np.random.normal(75, 10)
for i, exam in enumerate(exams):
# 每次考试略有提高
score = base_score + i * 2 + np.random.normal(0, 3)
data.append({'student': student, 'exam': exam, 'score': score})
df_repeated = pd.DataFrame(data)
print("重复测量数据预览:")
print(df_repeated.head(12))
重复测量数据分析
# 计算每个学生的考试平均值
student_exam_means = df_repeated.groupby(['student', 'exam'])['score'].mean().reset_index()
print("\n每位学生各次考试平均分:")
print(student_exam_means.pivot(index='student', columns='exam', values='score'))
# 执行重复测量方差分析
model_repeated = ols('score ~ C(exam) + C(student)', data=df_repeated).fit()
anova_repeated = anova_lm(model_repeated, typ=2)
print("\n重复测量方差分析表:")
print(anova_repeated)
# 检查时间效应
exam_effect_p = anova_repeated.loc['C(exam)', 'PR(>F)']
print(f"\n考试时间效应 p值: {exam_effect_p:.4f}")
案例4:可视化分析
# 箱线图展示各组分布
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 单因素箱线图
ax1 = axes[0, 0]
df.boxplot(column='score', by='method', ax=ax1)
ax1.set_title('不同教学方法成绩分布')
ax1.set_ylabel('成绩')
# 双因素交互图
ax2 = axes[0, 1]
sns.pointplot(data=df_2way, x='fertilizer', y='yield',
hue='irrigation', ax=ax2)
ax2.set_title('肥料与灌溉方式交互作用')
# 各组分布图
ax3 = axes[1, 0]
for method in df['method'].unique():
subset = df[df['method'] == method]['score']
sns.kdeplot(subset, label=f'方法 {method}', ax=ax3)
ax3.set_title('各组成绩分布密度')
ax3.legend()
# 双因素箱线图
ax4 = axes[1, 1]
sns.boxplot(data=df_2way, x='fertilizer', y='yield',
hue='irrigation', ax=ax4)
ax4.set_title('双因素分析箱线图')
plt.tight_layout()
plt.show()
案例5:事后检验(Post-hoc Analysis)
from statsmodels.stats.multicomp import pairwise_tukeyhsd
# 如果单因素方差分析显著,进行事后检验
if p_value < 0.05:
# Tukey HSD事后检验
tukey_results = pairwise_tukeyhsd(df['score'], df['method'], alpha=0.05)
print("Tukey HSD事后检验结果:")
print(tukey_results)
# 可视化事后检验结果
fig = tukey_results.plot_simultaneous()
plt.title('Tukey HSD事后检验')
plt.show()
完整分析函数
def comprehensive_anova_analysis(df, dependent_var, group_var, alpha=0.05):
"""
完整的方差分析函数
Parameters:
df: DataFrame
dependent_var: 因变量列名
group_var: 分组变量列名
alpha: 显著性水平
"""
print("="*50)
print(f"方差分析报告")
print(f"因变量: {dependent_var}")
print(f"分组变量: {group_var}")
print("="*50)
# 1. 描述性统计
print("\n1. 各组描述性统计:")
print(df.groupby(group_var)[dependent_var].describe())
# 2. 方差齐性检验
groups = [group[dependent_var].values for name, group in df.groupby(group_var)]
# Levene检验
from scipy.stats import levene
levene_stat, levene_p = levene(*groups)
print(f"\n2. 方差齐性检验 (Levene):")
print(f" Levene统计量: {levene_stat:.4f}")
print(f" p值: {levene_p:.4f}")
if levene_p < alpha:
print(" 警告:方差不齐性,建议使用Welch ANOVA")
# 3. 方差分析
print(f"\n3. 方差分析结果:")
groups_values = [df[df[group_var] == val][dependent_var].values
for val in df[group_var].unique()]
f_stat, p_val = stats.f_oneway(*groups_values)
print(f" F统计量: {f_stat:.4f}")
print(f" p值: {p_val:.6f}")
if p_val < alpha:
print(f" 在{alpha}显著性水平下,各组均值存在显著差异")
else:
print(f" 在{alpha}显著性水平下,各组均值无显著差异")
# 4. 效应量
from scipy.stats import f_oneway
# 计算eta-squared
ss_between = sum([len(g) * (np.mean(g) - np.mean(df[dependent_var]))**2
for g in groups_values])
ss_total = sum((df[dependent_var] - np.mean(df[dependent_var]))**2)
eta_squared = ss_between / ss_total
print(f"\n4. 效应量 (η²): {eta_squared:.4f}")
return {
'f_statistic': f_stat,
'p_value': p_val,
'eta_squared': eta_squared,
'levene_p': levene_p
}
# 使用完整分析函数
result = comprehensive_anova_analysis(df, 'score', 'method')
这些案例展示了如何使用Pandas和统计库进行各种类型的方差分析,关键点包括:
- 数据准备:使用
groupby()进行数据分组 - 模型构建:使用
ols()和anova_lm()进行方差分析 - 假设检验:检查正态性和方差齐性
- 事后检验:如果主效应显著,进行多重比较
- 可视化:使用箱线图和交互图展示结果
根据具体研究问题选择合适的方差分析类型,并注意检查分析假设的满足情况。