mannwhitneyu 批量计算后 p 值变了:auto 会看其他切片的重复值
SciPy1.18.1的mannwhitneyu在auto模式下按整次调用判断是否有ties;一组样本出现重复值,可让另一组从exact转为asymptotic。逐组调用可保留每组独立的自动选择。
把多组 Mann–Whitney U 检验从循环改成一次带 axis 的调用,某一组样本完全没变,p 值却变了。如果使用 method="auto",且批次里同时包含有重复值和无重复值的样本对,应检查计算方法是否被整个批次共同选择。
SciPy 1.18.1 的自动选择会检查整次调用中是否存在 ties。这里 ties 指同一组两份样本合并后的重复值,并不是不同组之间恰好出现同一个数字。任意切片有 ties,都可能使其他切片也采用渐近方法。
数据没变,选择的方法变了
一个无 ties 的小样本对可以写为:
import numpy as np
from scipy.stats import mannwhitneyu
x = np.array([0, 1, 2, 3, 9], dtype=float)
y = np.array([4, 5, 6, 7, 8, 10, 11], dtype=float)
standalone = mannwhitneyu(x, y, method="auto", alternative="two-sided")
当至少一份样本数量不超过 8、且无 ties 时,这条自动路径可选择 exact。将同一组与另一个含 ties 的切片合成批次后,auto 可改选 asymptotic。上述样本的 U 仍为 5,exact p 值约为 0.04798,带连续性修正的渐近 p 值约为 0.05132。
这两个数分别与各自算法一致,问题在于调用组合改变了方法选择,不能据此说渐近计算把另一个切片的方差错误加了进来。渐近法的 ties 校正仍按切片计算。这个例子跨过 0.05 也不意味着可以选择较小的结果来报告。
需要每组独立选择时,保留逐组调用
如果应用要求每个样本对与单独调用一致,可继续逐组执行 auto。以下片段限定 X、Y 为同样行数的二维 NumPy 浮点数组,每行分别是一组样本,且没有 NaN:
if X.ndim != 2 or Y.ndim != 2 or X.shape[0] != Y.shape[0]:
raise ValueError("X and Y must have matching sample-pair rows")
results = [
mannwhitneyu(a, b, method="auto", alternative="two-sided", use_continuity=True)
for a, b in zip(X, Y)
]
pvalues = np.array([result.pvalue for result in results])
X、Y 是原任务输入,不要求两份样本的列数相同。这里显式检查行数,避免 zip 静默丢掉多出来的样本对。逐组调用会增加调度成本,应按实际批次数评估;它保留的是独立 auto 选择,不提供新的统计模型。
也可以在分析方案本来就要求统一方法时显式指定方法,但要在看结果之前确定依据。不能对含 ties 的小样本一律强制 exact:该路径不做 ties 校正。置换方案、渐近近似和缺失样本处理各有适用条件,不能只为让批量与循环相同而随意替换。
验收方法与 p 值一起记录
对照中同时包含全无 ties、全有 ties和混合批次,并交换行序。每组记录原样本量、重复值情况、U、所用方法与 p 值。显式 exact 或 asymptotic 的对照有助于解释差异,但不能以两种方法碰巧给出相同数字作为自动选择一致的证明。
如果生产分析依赖逐组一致性,应保留这一检查,后续更新依赖时继续比较原循环与批量调用。含 NaN、广播或变长样本的任务还需另核有效样本量与缺失策略,不直接套用上面的二维无缺失片段。


