我一直在从不同的分布中采样随机数,并且刚刚意识到 numpy 二项式随机数与其他分布相比有多慢。例如
%timeit for x in range(100): np.random.binomial(100,0.5)
10000 loops, best of 3: 82.6 µs per loop
%timeit for x in range(100): np.random.uniform()
100000 loops, best of 3: 14.6 µs per loop
二项式数比均匀数多 6 倍!这是可以理解的,因为二项式是离散的并且需要更复杂的变换。但例如,如果我要求进行多次试验 n=0 或 n=1 的二项式,则花费的时间类似:
%timeit for x in range(100): np.random.binomial(0,0.5)
10000 loops, best of 3: 78.8 µs per loop
%timeit for x in range(100): np.random.binomial(1,0.5)
10000 loops, best of 3: 80.1 µs per loop
这似乎不是很有效,因为这些采样的结果应该是微不足道的:对于零次试验,结果应该始终为零,对于 1 次试验,它应该是简单的伯努利试验。例如,二项式的更快实现将是:
import numpy as np
def custombinomial(n,p):
if n == 0:
return 0
if n == 1:
x = np.random.uniform()
if x<p:
return 1
else:
return 0
else:
return np.random.binomial()
时间安排如下:
%timeit for x in range(100): custombinomial(0,0.5)
100000 loops, best of 3: 11.8 µs per loop
%timeit for x in range(100): custombinomial(1,0.5)
10000 loops, best of 3: 31.2 µs per loop
我确信对于更大的 n 值,这可以得到改进。我有什么理由错过 numpy 这么慢吗?是否有任何其他库可以提供更快的随机数(即使它包含某种 C/Cython)?
另外,我知道如果我想同时创建一堆随机数,即获取二项式分布数字的数组,那么 numpy 很好,但在许多情况下,分布 n 和 p 的参数会动态变化,因此调用单个随机数不会直接成为一种选择。是否可能有一种替代方案,其中生成均匀分布的随机数数组,并根据需要将它们转换为特定的二项式?