Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 生成一个随机的3元素整数数组,该数组的整数总和为3_Python_Arrays_Random_Numpy_Combinations - Fatal编程技术网

Python 生成一个随机的3元素整数数组,该数组的整数总和为3

Python 生成一个随机的3元素整数数组,该数组的整数总和为3,python,arrays,random,numpy,combinations,Python,Arrays,Random,Numpy,Combinations,我需要用随机整数填充一个由三个元素组成的numpy数组,使数组的总和为三(例如[0,1,2]) 据我估计,有10种可能的阵列: 111,, 012, 021, 102, 120, 201, 210, 300, 030, 003 我的想法是使用randint随机生成1到10之间的整数,然后使用查找表从上面的组合列表中填充数组 有谁知道更好的方法吗?以下是我是如何做到的: >>> import numpy as np >>> a=np.array([[1,1,1]

我需要用随机整数填充一个由三个元素组成的numpy数组,使数组的总和为三(例如
[0,1,2]

据我估计,有10种可能的阵列:

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

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

有谁知道更好的方法吗?

以下是我是如何做到的:

>>> 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])

以下是一种针对任意数组大小/总和执行此操作的简单编程方法:

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)
当然,这将与所需的总和成比例地降低速度,但对于较小的值是可以的

或者,我们可以通过从多项式分布中提取样本来表达这一点,对于多项式分布,NumPy中提供了一个函数(请参见),如下所示:

def n_ints_summing_to_v(n, v):
  return np.random.multinomial(v, ones((n)) / float(n))

这要快得多

这个问题可以在一般情况下解决,其中元素的数量及其总和都是可配置的。下面的解决方案的一个优点是,它不需要生成所有可能性的列表。其思想是按顺序选取随机数,每个随机数都小于所需的总和。每次选择一个数字时,所需的总和都会减少:

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()
为第一个数字提供的统一分布。

对于这个问题,在更大的范围内进行了大量讨论。可能有助于读取点均匀性/偏差。虽然如果这里的问题是关于在这种受限情况下的最佳方式,那么我认为这不是一个重复