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

如何使用numpy.random.choice生成前缀相同、长度递增的随机序列

问题原因

你当前实现未达预期的核心原因是:numpy 旧版本 np.random.choice 在 replace=False 且传入概率参数时,内部采用批量加权无替换采样算法,而非逐次抽取样本,即使固定随机种子,不同采样长度的结果也无法保证前缀一致性。


方案1:预生成全量序列(适合n不大的场景,实现最简)

核心逻辑:固定种子后一次性生成全部n个无重复的加权随机序列,后续任意阶段需要多长就取前多少位,天然满足前缀一致、无重复的要求,仅需存储一个长度为n的数组即可。

import numpy as np

n = 100
prob = np.random.choice(100, n)
prob = prob / np.sum(prob)

# 全局固定种子,预生成全量序列
np.random.seed(123)
full_sequence = np.random.choice(n, size=n, replace=False, p=prob)

# 不同运行阶段按需取前k位即可
for i in np.arange(10, 100, 10):
    selected = full_sequence[:i]
    print(f"{i}: {selected}")

方案2:迭代式逐次采样(适合n较大,无需预存全量序列)

如果你的n规模很大,预存全量序列占用内存过高,可实现逐次采样的生成器,每次调用返回下一个符合权重的无重复样本,按需取用即可,不需要提前生成全量序列,也无需强制存储已生成的历史序列。

import numpy as np

def weighted_sample_generator(n, prob, seed=None):
    rng = np.random.default_rng(seed)
    remaining_indices = np.arange(n)
    remaining_prob = prob.copy()
    while len(remaining_indices) > 0:
        # 按当前剩余样本的概率权重抽取1个样本
        selected_pos = rng.choice(len(remaining_indices), p=remaining_prob/remaining_prob.sum())
        selected_val = remaining_indices[selected_pos]
        yield selected_val
        # 移除已抽取的样本和对应概率
        remaining_indices = np.delete(remaining_indices, selected_pos)
        remaining_prob = np.delete(remaining_prob, selected_pos)

# 全局初始化生成器,固定种子保证可复现
prob = np.random.choice(100, 100)
prob = prob / np.sum(prob)
gen = weighted_sample_generator(n=100, prob=prob, seed=123)

# 不同运行阶段按需取数即可
# 阶段1:取10个样本
selected_10 = [next(gen) for _ in range(10)]
print(f"10: {selected_10}")
# 阶段2:取20个样本,前缀和前10个完全一致
selected_20 = selected_10 + [next(gen) for _ in range(10)]
print(f"20: {selected_20}")
# 阶段3:取30个样本,前缀和前20个完全一致
selected_30 = selected_20 + [next(gen) for _ in range(10)]
print(f"30: {selected_30}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 06:06:00