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

如何基于种子数组高效生成对应一致的大规模随机数列表?

高效实现基于整数ID的一致性随机数生成(大规模数组场景)

问题概述

需要实现函数接收整数数组,返回等长随机数数组,同一输入值对应的随机数必须固定不变。例如输入[1,2,3]和[3,2,3]时,数值3对应的随机数完全一致。

原实现通过遍历每个元素创建独立随机数生成器(RNG),处理10万元素耗时约5秒,无法支撑2亿级别的输入规模。实际场景为对2000亿粒子的模拟快照做1%下采样:每个粒子带超大范围非负ID,同一粒子会出现在多个快照中,需保证其在所有快照里的保留状态一致;内存有限,每次仅能加载2亿级别的子快照数据。

原低效实现

import numpy as np

def random_array(input_array):
    rng_list = [np.random.default_rng(seed=i) for i in input_array]
    return [rng.random() for rng in rng_list]

input_a = np.array([1, 2, 3])
input_b = np.array([3, 2, 3])

print(random_array(input_a)) # [0.5118216247002567, 0.2616121342493164, 0.08564916714362436]
print(random_array(input_b)) # [0.08564916714362436, 0.2616121342493164, 0.08564916714362436]

高效解决方案

核心思路:避免重复处理相同ID,通过批量操作或确定性哈希转换替代逐个创建RNG的开销。

方案1:唯一值映射+批量RNG生成

利用np.unique提取唯一ID,仅为每个唯一值生成一次随机数,再映射回原数组。适合重复ID占比较高的场景。

import numpy as np

def random_array_fast(input_array):
    # 提取唯一值及原数组的索引映射
    unique_vals, inv_indices = np.unique(input_array, return_inverse=True)
    # 为每个唯一值生成固定随机数
    random_vals = np.array([np.random.default_rng(seed=val).random() for val in unique_vals])
    # 映射回原数组长度
    return random_vals[inv_indices]

# 测试
input_a = np.array([1, 2, 3, 4, 5])
input_b = np.array([3, 2, 3])
print(random_array_fast(input_a))
print(random_array_fast(input_b)) # 3、2对应的随机数与input_a完全一致

方案2:确定性哈希/LCG转换(最优性能)

直接通过哈希函数或线性同余生成器(LCG)将ID转换为[0,1)区间的浮点数,完全避免创建RNG实例,性能拉满。

哈希实现

import numpy as np
import hashlib

def id_to_random(id_val):
    # 将整数ID转为字节串,计算SHA256哈希后取前8字节转64位整数
    byte_id = id_val.to_bytes(8, byteorder='big', signed=False)
    hash_int = int.from_bytes(hashlib.sha256(byte_id).digest()[:8], byteorder='big')
    # 归一化到[0,1)区间
    return hash_int / (2**64)

# 向量化处理数组
vectorized_id_to_random = np.vectorize(id_to_random, otypes=[np.float64])

def random_array_hash(input_array):
    return vectorized_id_to_random(input_array)

LCG实现(更快)

import numpy as np

def random_array_lcg(input_array):
    # 选用周期长、分布均匀的LCG参数
    a = 1103515245
    c = 12345
    m = 2**31
    # 生成伪随机数并归一化
    random_int = (a * input_array + c) % m
    return random_int / m

方案3:磁盘缓存(极端唯一值场景)

若唯一值数量极大且需重复处理,可将ID-随机数映射缓存到sqlite3或numpy.savez文件中,仅在重复处理同一ID时推荐使用,避免额外IO开销。

性能对比

方案10万元素耗时2亿元素预估耗时
原实现~5秒无法支撑
唯一值映射方案~0.05秒~10秒(依唯一值占比)
哈希/LCG方案~0.01秒~3-5秒

实际下采样应用

直接生成随机数后与阈值比较得到保留掩码,保证同一粒子在所有快照中的状态一致:

def get_sample_mask(input_ids, keep_prob=0.01):
    random_vals = random_array_lcg(input_ids)
    return random_vals < keep_prob

# 示例:加载子快照ID生成过滤掩码
sub_snapshot_ids = np.load("sub_snapshot_1_ids.npy")
mask = get_sample_mask(sub_snapshot_ids)
kept_particles = sub_snapshot_data[mask]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 19:47:03