最快的方法在python中生成1,000,000多个随机数

San*_*dro 24 python random performance numpy

我目前正在python中编写一个需要生成大量随机数的应用程序.FAST.目前我有一个方案,使用numpy生成一个巨大的批次中的所有数字(一次大约约500,000).虽然这似乎比python的实现更快.我仍然需要它更快.有任何想法吗?我愿意用C语言编写它并将其嵌入程序中或者用它来完成它.

对随机数的限制:

  • 一组7个数字,可以都有不同的边界:
    • 例如:[0-X1,0-X2,0-X3,0-X4,0-X5,0-X6,0-X7]
    • 目前我正在生成一个包含7个数字的列表,其中随机值来自[0-1],然后乘以[X1..X7]
  • 一组13个数字,总计为1
    • 目前只生成13个数字,然后除以它们的总和

有任何想法吗?预先计算这些数字并将它们存储在一个文件中会使这更快吗?

谢谢!

Joe*_*ton 13

你可以通过你最初描述的内容(生成一堆随机数并相应地相乘和分割)来加快mtrw上面发布的内容的速度......

此外,您可能已经知道这一点,但在使用大型numpy数组时,请确保就地执行操作(*=,/ =,+ =等).它在内存使用方面与大型阵列产生巨大差异,并且也会带来相当大的速度提升.

In [53]: def rand_row_doubles(row_limits, num):
   ....:     ncols = len(row_limits)
   ....:     x = np.random.random((num, ncols))
   ....:     x *= row_limits                  
   ....:     return x                          
   ....:                                       
In [59]: %timeit rand_row_doubles(np.arange(7) + 1, 1000000)
10 loops, best of 3: 187 ms per loop
Run Code Online (Sandbox Code Playgroud)

相比于:

In [66]: %timeit ManyRandDoubles(np.arange(7) + 1, 1000000)
1 loops, best of 3: 222 ms per loop
Run Code Online (Sandbox Code Playgroud)

这不是一个巨大的差异,但如果你真的担心速度,那就是它.

只是为了表明它是正确的:

In [68]: x.max(0)
Out[68]:
array([ 0.99999991,  1.99999971,  2.99999737,  3.99999569,  4.99999836,
        5.99999114,  6.99999738])

In [69]: x.min(0)
Out[69]:
array([  4.02099599e-07,   4.41729377e-07,   4.33480302e-08,
         7.43497138e-06,   1.28446819e-05,   4.27614385e-07,
         1.34106753e-05])
Run Code Online (Sandbox Code Playgroud)

同样,对于你的"行总和为一"部分......

In [70]: def rand_rows_sum_to_one(nrows, ncols):
   ....:     x = np.random.random((ncols, nrows))
   ....:     y = x.sum(axis=0)
   ....:     x /= y
   ....:     return x.T
   ....:

In [71]: %timeit rand_rows_sum_to_one(1000000, 13)
1 loops, best of 3: 455 ms per loop

In [72]: x = rand_rows_sum_to_one(1000000, 13)

In [73]: x.sum(axis=1)
Out[73]: array([ 1.,  1.,  1., ...,  1.,  1.,  1.])
Run Code Online (Sandbox Code Playgroud)

老实说,即使你在C中重新实现了一些东西,我也不确定你能不能在这个问题上打败numpy ......但我可能会非常错!


mtr*_*trw 6

编辑创建的函数返回完整的数字集,而不是一次返回一行. 编辑2使功能更加pythonic(和更快),为第二个问题添加解决方案

对于第一组数字,您可以考虑numpy.random.randint或采用numpy.random.uniform哪些参数lowhigh参数.在指定范围内生成7 x 1,000,000个数字的数组似乎在我的2 GHz机器上花费<0.7秒:

def LimitedRandInts(XLim, N):
    rowlen = (1,N)
    return [np.random.randint(low=0,high=lim,size=rowlen) for lim in XLim]

def LimitedRandDoubles(XLim, N):
    rowlen = (1,N)
    return [np.random.uniform(low=0,high=lim,size=rowlen) for lim in XLim]

>>> import numpy as np
>>> N = 1000000 #number of randoms in each range
>>> xLim = [x*500 for x in range(1,8)] #convenient limit generation
>>> fLim = [x/7.0 for x in range(1,8)]
>>> aa = LimitedRandInts(xLim, N)
>>> ff = LimitedRandDoubles(fLim, N)
Run Code Online (Sandbox Code Playgroud)

这将返回[0,xLim-1]中的整数或[0,fLim]中的浮点数.在我的2 GHz单核机器上,整数版需要~0.3秒,双倍~0.66.

对于第二组,我使用了@Joe Kingston的建议.

def SumToOneRands(NumToSum, N):
    aa = np.random.uniform(low=0,high=1.0,size=(NumToSum,N)) #13 rows by 1000000 columns, for instance
    s = np.reciprocal(aa.sum(0))
    aa *= s
    return aa.T #get back to column major order, so aa[k] is the kth set of 13 numbers

>>> ll = SumToOneRands(13, N)
Run Code Online (Sandbox Code Playgroud)

这需要约1.6秒.

在所有情况下,result[k]为您提供第k组数据.