生成随机3元素Numpy整数数组,总和为3

时间:2013-11-26 09:20:04

标签: python arrays random numpy combinations

我需要用随机整数填充三个元素的numpy数组,这样数组的总和就是三(例如[0,1,2])。

根据我的估算,有10个可能的数组:

111 012, 021, 102, 120, 201, 210, 300, 030, 003

我的想法是使用randint随机生成1到10之间的整数,然后使用查找表从上面的组合列表中填充数组。

有谁知道更好的方法?

3 个答案:

答案 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()为第一位数提供的均匀分布。