You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多次数组重采样取众数的高效方法及numpy工具适用性探讨

用numpy.random.choice实现众数的高效自助法与置换检验

核心结论

完全可以用numpy.random.choice实现针对众数的高效自助法,它的矢量化特性能大幅提升重采样效率,非常适合构建大规模的自助分布和置换检验零分布。


一、众数自助法的高效实现

自助法的核心是有放回重采样,numpy.random.choice支持replace=True参数,完美匹配需求,且比Python原生循环快几个数量级。

1. 生成自助重采样样本

直接生成批量重采样数据,形状为(重采样次数, 原数据长度):

import numpy as np
from scipy.stats import mode

# 原始离散数据
raw_data = np.array([1, 2, 2, 3, 3, 3, 4, 4, 4, 4])
n_bootstrap = 10000  # 重采样次数

# 批量生成自助样本:矢量化操作,效率极高
bootstrap_samples = np.random.choice(raw_data, size=(n_bootstrap, len(raw_data)), replace=True)

2. 快速计算每个样本的众数

如果数据是离散整数,用np.bincount结合np.argmax比scipy.stats.mode更快,适合大数据量场景:

def calc_mode(arr):
    # 统计每个值的出现次数,返回频率最高的值
    count = np.bincount(arr)
    return np.argmax(count)

# 批量计算所有自助样本的众数
bootstrap_modes = np.apply_along_axis(calc_mode, axis=1, arr=bootstrap_samples)

3. 构建众数的概率分布

通过统计众数的频率即可得到分布:

# 统计众数出现频率
mode_counts = np.bincount(bootstrap_modes)
mode_probs = mode_counts / n_bootstrap

# 例如,输出每个众数对应的概率
for val, prob in enumerate(mode_probs):
    if prob > 0:
        print(f"众数{val}: 概率{prob:.4f}")

二、基于置换检验的分布比较

假设要检验两组数据的众数是否存在显著差异,可按以下步骤实现,numpy.random.choice依然是核心工具。

1. 定义检验统计量

用两组众数的绝对差值作为检验统计量:|mode_A - mode_B|

2. 实现置换检验

# 两组待比较数据
data_A = np.array([1, 2, 2, 3, 3])
data_B = np.array([3, 3, 4, 4, 4])

# 计算观察到的统计量
observed_mode_A = calc_mode(data_A)
observed_mode_B = calc_mode(data_B)
observed_diff = abs(observed_mode_A - observed_mode_B)

n_permutations = 10000
combined_data = np.concatenate([data_A, data_B])
len_A = len(data_A)

# 构建零分布
permutation_diffs = []
for _ in range(n_permutations):
    # 无放回打乱合并数据,模拟置换
    shuffled = np.random.choice(combined_data, size=len(combined_data), replace=False)
    perm_A = shuffled[:len_A]
    perm_B = shuffled[len_A:]
    # 计算置换后的统计量
    perm_diff = abs(calc_mode(perm_A) - calc_mode(perm_B))
    permutation_diffs.append(perm_diff)

# 计算p值
p_value = np.mean(np.array(permutation_diffs) >= observed_diff)
print(f"置换检验p值: {p_value:.4f}")

关键优化点

  • 尽量用矢量化操作替代循环,numpy.random.choice的批量采样是核心效率保障
  • 针对离散数据,优先用np.bincount计算众数,避免scipy.stats.mode的额外开销
  • 若需更大规模的重采样/置换,可结合numba对众数计算函数加速,进一步压缩时间

内容的提问来源于stack exchange,提问作者Anthony Petruzzio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 16:40:40