本文目录导读:

我来详细介绍如何使用Pandas进行数据分组效应量计算,包括常见的效应量指标及其Python实现。
准备数据
import pandas as pd
import numpy as np
from scipy import stats
import pingouin as pg
import warnings
warnings.filterwarnings('ignore')
# 创建示例数据
np.random.seed(42)
data = pd.DataFrame({
'group': np.repeat(['A', 'B', 'C'], 50),
'score': np.concatenate([
np.random.normal(70, 10, 50), # 组A
np.random.normal(75, 12, 50), # 组B
np.random.normal(65, 15, 50) # 组C
]),
'category': np.random.choice(['X', 'Y'], 150)
})
print(data.head())
print(f"\n数据集形状: {data.shape}")
分组描述统计
# 分组描述统计
group_stats = data.groupby('group')['score'].agg([
'count', 'mean', 'std', 'min', 'max',
lambda x: x.quantile(0.25),
lambda x: x.quantile(0.75)
]).round(2)
group_stats.columns = ['计数', '均值', '标准差', '最小值', '最大值', '25%分位', '75%分位']
print("各组描述统计:")
print(group_stats)
常见效应量计算
1 Cohen's d (两两比较)
def cohens_d(group1, group2):
"""计算Cohen's d效应量"""
n1, n2 = len(group1), len(group2)
mean1, mean2 = np.mean(group1), np.mean(group2)
var1, var2 = np.var(group1, ddof=1), np.var(group2, ddof=1)
# 合并标准差
pooled_std = np.sqrt(((n1-1)*var1 + (n2-1)*var2) / (n1+n2-2))
d = (mean1 - mean2) / pooled_std
return d
# 计算所有组对之间的Cohen's d
groups = data.groupby('group')['score']
# 使用循环计算
effect_sizes = {}
group_names = list(groups.groups.keys())
for i in range(len(group_names)):
for j in range(i+1, len(group_names)):
g1 = groups.get_group(group_names[i])
g2 = groups.get_group(group_names[j])
d = cohens_d(g1, g2)
effect_sizes[f"{group_names[i]} vs {group_names[j]}"] = round(d, 3)
print("Cohen's d效应量:")
for pair, d in effect_sizes.items():
print(f"{pair}: {d}")
2 Hedges' g (小样本校正)
def hedges_g(group1, group2):
"""计算Hedges' g(Cohen's d的校正版本)"""
n1, n2 = len(group1), len(group2)
d = cohens_d(group1, group2)
# 校正因子
correction = 1 - (3 / (4*(n1+n2) - 9))
g = d * correction
return g
print("\nHedges' g 效应量:")
for i in range(len(group_names)):
for j in range(i+1, len(group_names)):
g1 = groups.get_group(group_names[i])
g2 = groups.get_group(group_names[j])
g = hedges_g(g1, g2)
print(f"{group_names[i]} vs {group_names[j]}: {round(g, 3)}")
3 Eta-squared (η²) 用于方差分析
def eta_squared(data, dv, group_col):
"""计算Eta-squared效应量"""
# 总平方和
grand_mean = data[dv].mean()
ss_total = np.sum((data[dv] - grand_mean)**2)
# 组间平方和
ss_between = 0
for name, group in data.groupby(group_col):
group_mean = group[dv].mean()
ss_between += len(group) * (group_mean - grand_mean)**2
# 组内平方和
ss_within = ss_total - ss_between
# Eta-squared
eta_sq = ss_between / ss_total
return eta_sq
eta_sq = eta_squared(data, 'score', 'group')
print(f"\nEta-squared: {round(eta_sq, 4)}")
print(f"解释:组间差异可解释 {round(eta_sq*100, 2)}% 的方差")
4 Glass's delta
def glass_delta(group1, group2, control_idx=0):
"""计算Glass's delta(使用对照组标准差)"""
mean1, mean2 = np.mean(group1), np.mean(group2)
std_control = np.std([group1, group2][control_idx], ddof=1)
delta = (mean1 - mean2) / std_control
return delta
print("\nGlass's delta (以第一组为对照):")
base_group = groups.get_group(group_names[0])
for i in range(1, len(group_names)):
comp_group = groups.get_group(group_names[i])
delta = glass_delta(comp_group, base_group)
print(f"{group_names[i]} vs {group_names[0]}: {round(delta, 3)}")
使用统计库计算效应量
# 使用pingouin库计算效应量
def calculate_effect_sizes_pingouin(data, dv, between):
"""使用pingouin计算多种效应量"""
from pingouin import pairwise_tests
# 两两比较(自动计算Cohen's d)
pairwise = pairwise_tests(data=data, dv=dv, between=between,
effsize='cohen')
print("Pingouin两两比较结果:")
print(pairwise[['Contrast', 'A', 'B', 'cohen-d']])
return pairwise
try:
results = calculate_effect_sizes_pingouin(data, 'score', 'group')
except:
print("请先安装pingouin: pip install pingouin")
分组效应量可视化
import matplotlib.pyplot as plt
import seaborn as sns
def plot_effect_sizes(data, groups, dv):
"""可视化效应量"""
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 1. 箱线图
ax = axes[0, 0]
sns.boxplot(x=groups, y=dv, data=data, ax=ax)
ax.set_title('分组箱线图')
ax.set_xlabel('组别')
ax.set_ylabel('得分')
# 2. 分布图
ax = axes[0, 1]
for name, group in data.groupby(groups):
sns.kdeplot(data=group[dv], label=name, ax=ax)
ax.set_title('分组分布图')
ax.set_xlabel('得分')
ax.legend()
# 3. 均值和置信区间
ax = axes[1, 0]
group_means = data.groupby(groups)[dv].agg(['mean', 'std', 'count'])
group_means.columns = ['均值', '标准差', '样本量']
# 计算标准误
group_means['标准误'] = group_means['标准差'] / np.sqrt(group_means['样本量'])
x_pos = range(len(group_means))
ax.bar(x_pos, group_means['均值'], yerr=group_means['标准误']*1.96,
capsize=5, alpha=0.7)
ax.set_xticks(x_pos)
ax.set_xticklabels(group_means.index)
ax.set_title('分组均值(95%置信区间)')
ax.set_ylabel('均值')
# 4. 效应量热图
ax = axes[1, 1]
effect_matrix = np.zeros((len(group_names), len(group_names)))
for i in range(len(group_names)):
for j in range(len(group_names)):
if i != j:
g1 = groups.get_group(group_names[i])
g2 = groups.get_group(group_names[j])
effect_matrix[i, j] = cohens_d(g1, g2)
sns.heatmap(effect_matrix, annot=True, fmt='.2f',
xticklabels=group_names, yticklabels=group_names,
cmap='coolwarm', center=0, ax=ax)
ax.set_title('Cohen\'s d 效应量矩阵')
ax.set_xlabel('被比较组')
ax.set_ylabel('参考组')
plt.tight_layout()
plt.show()
# 调用可视化函数
plot_effect_sizes(data, 'group', 'score')
多变量分组效应量
# 多变量分组效应量计算
def multivariate_effect_size(data, dv_cols, group_col):
"""计算多变量分组效应量(基础版)"""
results = {}
for dv in dv_cols:
# 计算各组的均值和标准差
group_stats = data.groupby(group_col)[dv].agg(['mean', 'std'])
# 计算总均值
grand_mean = data[dv].mean()
# 计算Eta-squared
ss_between = 0
ss_total = np.sum((data[dv] - grand_mean)**2)
for name, group in data.groupby(group_col):
group_mean = group[dv].mean()
ss_between += len(group) * (group_mean - grand_mean)**2
eta_sq = ss_between / ss_total
# 计算总体效应量(类似Cohen's f)
cohens_f = np.sqrt(eta_sq / (1 - eta_sq))
results[dv] = {
'eta_squared': round(eta_sq, 4),
'cohens_f': round(cohens_f, 4),
'组均值': group_stats['mean'].to_dict(),
'组标准差': group_stats['std'].to_dict()
}
return pd.DataFrame(results).T
# 多变量分析
dv_cols = ['score'] # 可以添加更多变量
multivariate_results = multivariate_effect_size(data, dv_cols, 'group')
print("\n多变量效应量分析结果:")
print(multivariate_results.round(3))
效应量解释和报告
def interpret_effect_sizes(d_values):
"""解释效应量大小"""
def interpret_single(d):
if abs(d) < 0.2:
return "微小效应"
elif abs(d) < 0.5:
return "小效应"
elif abs(d) < 0.8:
return "中等效应"
else:
return "大效应"
interpretations = {pair: interpret_single(d)
for pair, d in d_values.items()}
return interpretations
# 生成效应量报告
def generate_effect_report(data, group_col, dv):
"""生成完整的效应量分析报告"""
groups = data.groupby(group_col)[dv]
group_names = list(groups.groups.keys())
report = []
report.append("=" * 50)
report.append("效应量分析报告")
report.append("=" * 50)
# 基本信息
report.append(f"\n分析变量: {dv}")
report.append(f"分组变量: {group_col}")
report.append(f"组数: {len(group_names)}")
report.append(f"总样本量: {len(data)}")
# 组间比较
report.append("\n两两组间效应量:")
for i in range(len(group_names)):
for j in range(i+1, len(group_names)):
g1 = groups.get_group(group_names[i])
g2 = groups.get_group(group_names[j])
d = cohens_d(g1, g2)
g = hedges_g(g1, g2)
# 效应量解释
if abs(d) < 0.2:
interpretation = "微小"
elif abs(d) < 0.5:
interpretation = "小"
elif abs(d) < 0.8:
interpretation = "中等"
else:
interpretation = "大"
report.append(f"\n{group_names[i]} vs {group_names[j]}:")
report.append(f" Cohen's d = {d:.3f} ({interpretation}效应)")
report.append(f" Hedges' g = {g:.3f}")
# 总体效应
eta_sq = eta_squared(data, dv, group_col)
report.append(f"\n总体效应量:")
report.append(f" Eta-squared = {eta_sq:.4f}")
report.append(f" 组间解释方差 = {eta_sq*100:.2f}%")
return "\n".join(report)
# 生成报告
report = generate_effect_report(data, 'group', 'score')
print(report)
高级分析:双因素分组效应量
def two_way_effect_sizes(data, dv, factor1, factor2):
"""计算双因素分组效应量"""
results = {}
# 主效应1
results[f'{factor1}主效应'] = {
'eta_squared': eta_squared(data, dv, factor1)
}
# 主效应2
results[f'{factor2}主效应'] = {
'eta_squared': eta_squared(data, dv, factor2)
}
# 交互作用效应(简化版)
data['interaction'] = data[factor1].astype(str) + '_' + data[factor2].astype(str)
# 计算交互效应量
eta_sq_total = eta_squared(data, dv, 'interaction')
eta_sq_f1 = results[f'{factor1}主效应']['eta_squared']
eta_sq_f2 = results[f'{factor2}主效应']['eta_squared']
# 交互效应的eta-squared
results['交互效应'] = {
'eta_squared': eta_sq_total - eta_sq_f1 - eta_sq_f2
}
return pd.DataFrame(results).T
# 执行双因素分析
two_way_results = two_way_effect_sizes(data, 'score', 'group', 'category')
print("\n双因素效应量分析:")
print(two_way_results.round(4))
这些代码提供了完整的Pandas数据分组效应量计算方案,包括:
- 常见效应量指标:Cohen's d、Hedges' g、Eta-squared、Glass's delta
- 自动化和可定制:支持多组比较和自定义效应量函数
- 可视化:提供直观的效应量展示
- 报告生成:自动生成效应量分析报告
- 高级分析:支持双因素和多变量效应量分析
使用时可以根据具体研究需求选择合适的效应量指标并调整参数。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播