我有一个数字列表和另一个与这些数字相对应的概率列表。我使用numpy.random.choice
创建一个随机的2d数组:
choice = numpy.random.choice([10, 22, 30], [10, 10], p=[0.45, 0.45, 0.10])
在choice
中应该是45个,45个两个和10个零但是经过几次运行后我永远得不到正确的分布。
unique, counts = numpy.unique(choice, return_counts=True)
print(dict(zip(unique, counts)))
{10: 49, 22: 37, 30: 14}
{10: 47, 22: 42, 30: 11}
{10: 40, 22: 51, 30: 9}
我错过了什么?
答案 0 :(得分:4)
您完全不知道分发中的抽样是如何在实践中起作用的。你永远不会“得到”正确的分布,你总是得到一个近似值,因为你正在抽样。
仅在样本数量非常大的情况下,您最终应收敛到目标分布。但由于抽样是一个随机过程,因此过程结果始终存在随机性。
这当然适用于使用(伪)随机数生成器生成数字。
答案 1 :(得分:2)
所以,如果你将硬币翻了一千次,你是否希望总是获得500个头?
如果你想控制每个结果的确切数量,你就不能依赖概率 - 相反,从每个结果所在的列表中选择(没有替换)具有所需的多重性:
numpy.random.choice([10] * 45 + [22] * 45 + [30] * 10, [10, 10], replace=False)
答案 2 :(得分:2)
Matias说的是真的。
如果你想创建一个正好有45个零,45个和10个二进制的数组,形状为(10,10)但是按随机顺序,你可以这样做:
import numpy as np
zeros = np.array([0]*45)
ones = np.array([1]*45)
twos = np.array([2]*10)
myarr = np.concatenate([zeros, ones, twos])
# Random permutation, followed by reshaping in (10, 10) form
choice = np.random.permutation(myarr).reshape(10,10)
unique, counts = np.unique(choice, return_counts=True)
print(dict(zip(unique, counts)))
{0: 45, 1: 45, 2: 10}
答案 3 :(得分:2)
采样不准确,你可以通过列出你想要的所有数字然后随机改组它来强制所有数字都在输出数组中:
import numpy
import numpy.random
numbers = numpy.asarray(45*[10]+45*[22]+10*[30])
print (numbers)
numpy.random.shuffle(numbers) # numbers is changed in place
choice = numbers.reshape((10,10))
print (choice)
unique, counts = numpy.unique(choice, return_counts=True)
print(dict(zip(unique, counts)))