这应该非常快,因为它使用 numpy。
如果它得到任何 0.0,它会自动重复随机化,但这不太可能。 while循环是在OP将非零要求调整到0.01以上之前编写的。要解决此问题,您可以修改 while 块以包含整个后续代码,并以类似于检测零所示的方式计算最后违反任何所需约束的次数。但当 L 与违反约束的概率相比较大时,速度可能会变慢。从某种意义上说,最容易遵守最初的要求>0.0
.
经过 while 循环后,L x n 矩阵的每个元素均匀分布在 (0.0,1.0) 上,没有任何 0 或 1。每行相加并用于形成尺度矩阵,然后将矩阵乘以随机矩阵以获得自动总和为 1.0 的行
import numpy as np
def random_proportions(L,n):
zeros = 1
while zeros>0:
x = np.random.random(size=(L,n))
zeros = np.sum(x==0.0)
sums = x.sum(axis=1)
scale = np.diag(1.0/sums)
return np.dot(scale, x)
编辑:上面生成了一个用于缩放的 LxL 矩阵,这是内存效率低下的。 L=10**6之前就会OOM。我们可以通过使用建议的广播标准化程序来解决这个问题这个答案 https://stackoverflow.com/a/8904762/103081
import numpy as np
def random_proportions(L,n):
zeros = 1
while zeros>0:
x = np.random.random(size=(L,n))
zeros = np.sum(x==0.0)
sums = x.sum(axis=1).reshape(L,1) # reshape for "broadcasting" effect
return x/sums
第二个版本将在具有 16GB RAM 的 AMD FX-8150 上在大约 1/3 秒内计算 100 万个大小为 10 的列表:
%timeit l = random_proportions(1000000,10)
1 loops, best of 3: 347 ms per loop