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

带权重的三分布1000万随机样本抽取实现求助

高效实现带权重的混合分布抽样(1000万样本)

问题需求

现有三个统计分布disbn_1、disbn_2、disbn_3,需按照权重w_1=0.75、w_2=0.2、w_3=0.05抽取总计1000万个随机变量。此前尝试两种方案均失败:

  • 方案一:为每个分布预生成1000万样本,再用np.random.choice按权重选择样本,未达到预期效果;
  • 方案二:尝试用生成器动态生成样本,但无法获取新样本。
    要求实现高效抽样,兼顾速度与内存占用。

错误原因分析

  1. 方案一问题:直接使用np.random.choice选择三个数组的元素时,默认逻辑是从数组索引中抽样,而非按权重分配各分布的样本数量。同时预生成3×1000万样本会占用大量不必要的内存。
  2. 方案二问题:当前代码中generators列表存储的是单个样本(rvs()无参数时默认生成1个样本),而非可重复调用的生成逻辑,因此无法生成新样本。

高效解决方案

核心思路:先按权重分配各分布的样本数量,再批量生成对应样本,最后合并打乱。批量生成样本是scipy/numpy的最优操作方式,内存占用低且速度快。

具体步骤

  • 用np.random.multinomial按权重分配1000万样本到三个分布,确保样本总数准确;
  • 针对每个分布,批量生成对应数量的样本,应用clip截断和偏移处理;
  • 合并所有样本并打乱顺序(若不需要随机顺序可省略打乱步骤)。

完整实现代码

import numpy as np
import scipy.stats as sp

# 定义分布参数与权重
min_1 = 10_000_000
max_1 = 8_000_000_000
par_1 = 1000
w_1 = 0.75
disbn_1 = sp.expon(scale=par_1)

min_2 = 2000000
max_2 = max_1
par_2 = 1.6
w_2 = 0.2
disbn_2 = sp.pareto(par_2, scale=min_2)

min_3 = 1000000
max_3 = max_1
par_3 = 455555
w_3 = 0.05
disbn_3 = sp.expon(scale=par_3)

total_samples = 10_000_000

# 按权重分配各分布的样本数量
counts = np.random.multinomial(total_samples, [w_1, w_2, w_3])
count_1, count_2, count_3 = counts

# 批量生成各分布的样本
samples_1 = np.clip(disbn_1.rvs(count_1) + min_1, a_min=0, a_max=max_1)
samples_2 = np.clip(disbn_2.rvs(count_2), a_min=0, a_max=max_2)
samples_3 = np.clip(disbn_3.rvs(count_3) + min_3, a_min=0, a_max=max_3)

# 合并所有样本并打乱顺序
final_samples = np.concatenate([samples_1, samples_2, samples_3])
np.random.shuffle(final_samples)

# 验证样本数量与权重分布
print(f"总样本数:{len(final_samples)}")
print(f"各分布实际样本数:{count_1}, {count_2}, {count_3}")
print(f"实际权重:{count_1/total_samples:.3f}, {count_2/total_samples:.3f}, {count_3/total_samples:.3f}")

方案优势

  • 内存高效:仅生成所需数量的样本,避免预生成冗余数据;
  • 速度快:利用scipy的批量rvs()方法,比单个生成样本效率高几个数量级;
  • 准确性高:通过multinomial确保样本总数严格为1000万,权重分布符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:32:05