在Python中生成1,000,000个以上随机数的最快方法

我目前正在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个数字,然后除以他们的总和
  • 有任何想法吗? 预先计算这些数字并将它们存储在文件中会使速度更快?

    谢谢!


    你可以通过完成你最初描述的内容(产生一串随机数并相乘和相除),从上面发布的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
    

    相比于:

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

    这不是一个巨大的差异,但如果你真的担心速度,这是一些东西。

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

    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])
    

    同样,对于你的“行总和”一部分...

    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.])
    

    老实说,即使你用C语言重新实现了一些东西,我也不确定你会在这个游戏中获得多少胜利......尽管我可能是错的!


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

    对于第一组数字,您可以考虑使用numpy.random.randintnumpy.random.uniform ,它们采用low参数和high参数。 在指定的范围内生成一个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)
    

    这将返回[0,xLim-1]中的整数或浮动[0,fLim]中的整数。 在我的2 GHz单核机器上,整数版本花费了〜0.3秒,双倍〜0.66。

    对于第二组,我使用了@Joe金斯顿的建议。

    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)
    

    这需要约1.6秒。

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


    尝试r = 1664525*r + 1013904223
    从“一种更快速的发生器”中的“Numerical Recipes in C”2nd Press,Press等人,isbn 0521431085,p。 284。
    np.random肯定是“更随机”; 参见线性同余发生器。

    在python中,像这样使用np.uint32

    python -mtimeit -s '
    import numpy as np
    r = 1
    r = np.array([r], np.uint32)[0]  # 316 py -> 16 us np 
        # python longs can be arbitrarily long, so slow
    ' '
    r = r*1664525 + 1013904223  # NR2 p. 284
    '
    
    链接地址: http://www.djcxy.com/p/96729.html

    上一篇: Fastest Way to generate 1,000,000+ random numbers in python

    下一篇: C++ random float number generation