我需要用随机整数填充三个元素的numpy数组,这样数组的总和就是三(例如[0,1,2]
)。
根据我的估算,有10个可能的数组:
111 012, 021, 102, 120, 201, 210, 300, 030, 003
我的想法是使用randint
随机生成1到10之间的整数,然后使用查找表从上面的组合列表中填充数组。
有谁知道更好的方法?
答案 0 :(得分:2)
我是这样做的:
>>> import numpy as np
>>> a=np.array([[1,1,1],[0,1,2],[0,2,1],[1,0,2],[1,2,0],[2,0,1],[2,1,0],[3,0,0],[0,3,0],[0,0,3]])
>>> a[np.random.randint(0,10)]
array([1, 2, 0])
>>> a[np.random.randint(0,10)]
array([0, 1, 2])
>>> a[np.random.randint(0,10)]
array([1, 0, 2])
>>> a[np.random.randint(0,10)]
array([3, 0, 0])
答案 1 :(得分:2)
对于任意数组大小/总和,这是一种天真的编程方式:
def n_ints_summing_to_v(n, v):
elements = (np.arange(n) == np.random.randint(0, n)) for i in range(v))
return np.sum(elements, axis=0)
当然,这将与所需的金额成比例地减速,但对于小值则可以。
或者,我们可以根据从Multinomial分布中抽取样本来表达这一点,NumPy中有一个函数(参见here),如下所示:
def n_ints_summing_to_v(n, v):
return np.random.multinomial(v, ones((n)) / float(n))
这要快得多!
答案 2 :(得分:1)
这个问题可以在一般情况下解决,其中元素的数量及其总和都是可配置的。以下解决方案的一个优点是它不需要生成所有可能性的列表。这个想法是按顺序选择随机数,每个数字都小于所需的总和。每次选择数字时,所需金额都会减少:
import numpy
def gen(numel = 3, sum = 3):
arr = numpy.zeros((numel,), dtype = numpy.int)
for i in range(len(arr) - 1): # last element must be free to fill in the sum
arr[i] = numpy.random.randint(0, sum + 1)
sum -= arr[i]
if sum == 0: break # Nothing left to do
arr[-1] = sum # ensure that everything adds up
return arr
print(gen())
此解决方案无法保证所有可能性都以相同的频率发生。在您列出的十种可能性中,四种以0开头,三种为1,两种为2,一种为3.这显然不是numpy.random.randint()
为第一位数提供的均匀分布。