
本文介绍如何使用 pandas 和 itertools.combinations 对 groupby 得到的多个分组进行两两配对,并批量执行 mann-whitney u 检验等统计函数,支持任意数量分组的通用化实现。
本文介绍如何使用 pandas 和 itertools.combinations 对 groupby 得到的多个分组进行两两配对,并批量执行 mann-whitney u 检验等统计函数,支持任意数量分组的通用化实现。
在数据分析中,常需对按某列(如 'age')分组后的子样本两两比较,例如进行非参数假设检验(如 Mann-Whitney U 检验)。当分组数量动态变化(如 6 组 → 15 种组合,n 组 → C(n,2) 种),手动枚举不可行,必须采用程序化、可扩展的方法。
核心思路是:不直接操作 df.groupby(...).groups 返回的索引字典(该结构仅含行号,缺失原始值),而是利用 GroupBy 对象本身——它天然支持迭代,每次返回 (group_name, Series) 元组,便于提取对应 'value' 列数据并传入统计函数。
以下为推荐的两种输出格式实现:
✅ 方案一:扁平化结果表(推荐用于后续分析与筛选)
from itertools import combinations
from scipy.stats import mannwhitneyu
import pandas as pd
# 假设 df 包含 'age' 和 'value' 列
groups = df.groupby('age')['value'] # GroupBy 对象,按 age 分组取 value 列
# 对所有两两组合应用 Mann-Whitney U 检验
results = {
(name_a, name_b): mannwhitneyu(data_a, data_b)
for (name_a, data_a), (name_b, data_b) in combinations(groups, 2)
}
# 转为 DataFrame,每行对应一对分组,列包含 statistic 和 pvalue
result_df = pd.DataFrame.from_dict(results, orient='index')
result_df.columns = ['statistic', 'pvalue']
result_df.index.names = ['group_a', 'group_b']该方式生成一个长格式表格(如 15 行 × 2 列),清晰展示每对组合的检验结果,便于按 pvalue 等条件过滤显著对比。
✅ 方案二:对称方阵(适用于热力图可视化或聚类)
from scipy.spatial.distance import squareform
# 提取唯一分组标签并排序,确保行列一致
group_labels = sorted(df['age'].unique())
# 生成所有组合的 p 值列表
pvalues = [
mannwhitneyu(data_a, data_b).pvalue
for (name_a, data_a), (name_b, data_b) in combinations(groups, 2)
]
# 转换为对称方阵(对角线为 0,因自身无需检验)
p_matrix = pd.DataFrame(
squareform(pvalues),
index=group_labels,
columns=group_labels
).sort_index().sort_index(axis=1)
# 可选:将对角线设为 NaN 或 0
import numpy as np
np.fill_diagonal(p_matrix.values, 0.0)此结构便于用 seaborn.heatmap(p_matrix) 直观呈现所有组间差异显著性,也利于下游聚类或多重检验校正(如 FDR)。
⚠️ 注意事项
-
确保目标列存在:
df.groupby('age')['value']中'value'必须是数值型列,否则mannwhitneyu报错; -
样本量要求:Mann-Whitney U 检验要求每组至少 5–10 个观测值以保证近似有效性;若某组样本过少(如单点
6.0: [21]),建议跳过或改用其他方法(如置换检验); -
多重检验校正:15 次检验下 α=0.05 的家庭误差率远高于 0.05,强烈建议对
pvalue列应用statsmodels.stats.multitest.multipletests进行 FDR/Bonferroni 校正; -
性能提示:对超大分组数(如 >100 组 → 近 5000 次检验),可考虑使用
joblib.Parallel并行加速。
通过组合 pandas.GroupBy 与 itertools.combinations,你获得了一种简洁、健壮且完全自动化的两两检验框架——无论输入数据有 3 组还是 30 组,代码零修改即可运行。

















