numpy 生成随机数列表,每个元素和总数都有限制

nwnhqdif  于 2022-12-04  发布在  其他
关注(0)|答案(2)|浏览(147)

假设我有一个值列表,例如:

limits = [10, 6, 3, 5, 1]

对于limits中的每一项,我需要生成一个小于或等于该项的随机数,但是,新随机列表中元素的总和必须等于指定的总和。
例如,如果total = 10,则一个可能的随机列表是:

random_list = [2, 1, 3, 4, 0]

其中random_listlimits的长度相同,random_list中的每个元素都小于或等于limitssum(random_list) = total中的对应元素。
如何生成这样一个列表?我是开放的(和更喜欢)使用numpy,scipy,或Pandas。

v09wglhw

v09wglhw1#

要生成这样的列表,可以使用numpy的random.multinomial函数。该函数允许您生成一个随机数列表,这些随机数的总和为指定的总和,其中每个数字都是从指定大小的不同bin中选择的。
例如,若要产生5个总和为10的随机数清单,其中第一个数字可以是0到10之间的任何整数,第二个数字可以是0到6之间的任何整数,依此类推,您可以使用下列程式码:

import numpy as np

limits = [10, 6, 3, 5, 1]
total = 10

random_list = np.random.multinomial(total, [1/x for x in limits])

这将生成一个5个随机数的列表,这些随机数之和为10,并且小于或等于限值列表中的相应元素。
或者,可以使用numpy的random.randint函数生成小于或等于limits列表中相应元素的随机数,然后使用循环将这些数字相加,直到总和等于指定的总和。

import numpy as np

limits = [10, 6, 3, 5, 1]
total = 10

random_list = []

# Generate a random number for each element in limits
for limit in limits:
    random_list.append(np.random.randint(limit))

# Keep adding random numbers until the sum equals the total
while sum(random_list) != total:
    random_list[np.random.randint(len(random_list))] += 1

这两种方法都可以生成一个随机数列表,这些随机数的总和达到指定的总和,并且小于或等于极限列表中的相应元素。
编辑@gerges
要生成一个随机数列表,这些随机数的总和为指定的总和,并且小于或等于极限列表中的相应元素,可以使用numpy函数random.multinomial和random. randint的组合。
下面是一个示例,说明如何执行此操作:

import numpy as np

limits = [10, 6, 3, 5, 1]
total = 10

# Generate a list of random numbers that sum to the total using the multinomial function
random_list = np.random.multinomial(total, [1/x for x in limits])

# Use the randint function to ensure that each number is less than or equal to the corresponding limit
for i, limit in enumerate(limits):
    random_list[i] = np.random.randint(random_list[i], limit+1)

# Check that the sum of the numbers in the list equals the specified total and that each number is less than or equal to the corresponding limit
assert sum(random_list) == total
for i, number in enumerate(random_list):
    assert number <= limits[I]

此方法使用多项式函数生成一个随机数列表,然后使用randint函数确保每个数字都小于或等于相应的限制。这保证了生成的数字列表的总和将等于指定的总和,并且将小于或等于限制列表中的相应元素。

2uluyalo

2uluyalo2#

找到了我要找的东西:hypergeometric distribution类似于二项式,但没有替换。
分布available in numpy

import numpy as np

gen = np.random.Generator(np.random.PCG64(seed))
random_list = gen.multivariate_hypergeometric(limits, total)

# array([4, 4, 1, 1, 0])

此外,为了确保我没有误解分布,我对1000万个样本进行了合理性检查,并检查最大值是否始终在限制范围内

res = gen.multivariate_hypergeometric(limits, total, size=10000000) 

res.max(axis=0)

# array([10,  6,  3,  5,  1])

其与limits相同。

相关问题