如何生成含幸福度占比、样本量的统计表格并解决P值异常问题
幸福度统计表格与显著性检验问题解决
一、生成目标统计表格
你可以用Pandas按gender和age group分组,直接计算样本量与幸福度占比,再转成Markdown表格:
代码示例
import pandas as pd # 1. 处理性别分组统计 gender_stats = df.groupby('gender').agg( 样本量=('幸福度标记', 'count'), 幸福度占比=('幸福度标记', 'mean') ).reset_index() # 替换编码为实际标签 gender_stats['gender'] = gender_stats['gender'].map({1:'男性', 2:'女性', 3:'非二元性别'}) # 2. 处理年龄组分组统计 age_stats = df.groupby('age group').agg( 样本量=('幸福度标记', 'count'), 幸福度占比=('幸福度标记', 'mean') ).reset_index() # 替换编码为实际区间 age_stats['age group'] = age_stats['age group'].map({1:'18-24', 2:'25-44', 3:'45-64', 4:'65+'}) # 合并为总表格并输出Markdown格式 total_table = pd.concat([gender_stats, age_stats], keys=['性别分组', '年龄分组']).reset_index(level=0) print(total_table.to_markdown(index=False))
输出示例表格
| level_0 | gender | 样本量 | 幸福度占比 |
|---|---|---|---|
| 性别分组 | 男性 | 200 | 0.72 |
| 性别分组 | 女性 | 250 | 0.78 |
| 性别分组 | 非二元性别 | 30 | 0.67 |
| 年龄分组 | 18-24 | 120 | 0.65 |
| 年龄分组 | 25-44 | 220 | 0.75 |
| 年龄分组 | 45-64 | 100 | 0.78 |
| 年龄分组 | 65+ | 40 | 0.82 |
二、P值异常与层级P值缺失的原因及修正
核心原因
- 检验方法不匹配:你的幸福度标记是二元变量(0/1),如果误用了连续变量的检验方法(如t检验),或者只做了全局而非分层检验,会导致P值异常或无层级结果。
- 样本分布问题:若某分组样本量极小(如非二元性别组样本数不足),或所有分组的幸福度占比完全一致,检验会返回P=1(无显著性差异)。
- 工具参数设置错误:Mat Statter默认可能只做全局关联检验,未开启两两比较或分层检验,因此不会输出各层级的P值。
修正方案
针对二元因变量+分类自变量的场景,推荐两种方法:
1. 卡方检验+事后两两比较
用于检验分组与幸福度的整体关联,再通过Bonferroni校正做两两比较得到层级P值:
from scipy.stats import chi2_contingency # 性别与幸福度的卡方检验 gender_crosstab = pd.crosstab(df['gender'], df['幸福度标记']) chi2, p_global, dof, _ = chi2_contingency(gender_crosstab) print(f"性别全局卡方检验P值: {p_global}") # 年龄组同理 age_crosstab = pd.crosstab(df['age group'], df['幸福度标记']) chi2_age, p_age_global, dof_age, _ = chi2_contingency(age_crosstab) print(f"年龄组全局卡方检验P值: {p_age_global}")
2. 逻辑回归
直接输出每个分组相对于参考组的显著性P值,更适合多分类自变量:
import statsmodels.api as sm from statsmodels.formula.api import logit # 性别逻辑回归(以男性为参考组) df['gender'] = df['gender'].astype('category').cat.set_categories([1,2,3]) model_gender = logit('幸福度标记 ~ C(gender, Treatment(reference=1))', data=df).fit() print(model_gender.summary()) # 年龄组逻辑回归(以18-24为参考组) df['age group'] = df['age group'].astype('category').cat.set_categories([1,2,3,4]) model_age = logit('幸福度标记 ~ C(age group, Treatment(reference=1))', data=df).fit() print(model_age.summary())
内容的提问来源于stack exchange,提问作者ArRrgh
相关产品推荐
相关产品推荐

