我需要创建一个函数,它接受整数数组并返回与数组长度相同的随机数列表。但是,存在一个限制,即与输入数组中给定条目相对应的输出随机数应始终基于该条目相同。
例如,如果下面给出的
input_a
返回以下内容:
> input_a = np.array([1, 2, 3, 4, 5])
> random_array(input_a)
[0.51689016 0.62747792 0.16585436 0.63928942 0.30514275]
然后下面给出的
input_b
应返回以下内容:
> input_b = np.array([3, 2, 3])
> random_array(input_b)
[0.16585436 0.62747792 0.16585436]
请注意,对应于输入 3 的输出数字都是相同的,对应于输入 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]
它按预期工作,但是对于我需要它做的事情来说它非常慢 - 毫不奇怪,因为它正在对数组条目进行循环。此实现需要 5 秒左右才能在长度为 100,000 的输入数组上运行,并且我需要对比这大得多的输入执行此操作。
我怎样才能更有效地做到这一点?
首先想到的想法是将所有计算值缓存在函数外部的字典中,而不是重新计算它们。然而,对于非常大的数组,这种方法表现不佳。
对于非常大的数组,更好的方法是计算字典中所有唯一值的随机数,然后使用这些值创建随机数数组:
def random_array(input_array):
unique_vals = np.unique(input_array)
rng_dict = {val: np.random.default_rng(seed=val).random() for val in unique_vals}
return np.array([rng_dict[val] for val in input_array])
input_a = np.random.randint(0, 11, size=1_000_000)
input_b = np.random.randint(0, 11, size=1_000_000)
random_array(input_a)
random_array(input_b)
对于长度为 100,000 的数组,这大约需要
40ms
;对于长度为 1,000,000 的数组,这大约需要 0.4s
。