有效生成numpy.random.choice的多个实例而无需替换

发布于 2021-01-29 17:30:25

我是Python的新手。阅读时,请提及有关改进我的Python代码的其他建议。

问题: 如何在Python中生成包含随机数的8xN维数组? 约束条件是此数组的每一列必须包含8个抽奖,而不能从整数集[1,8]中进行替换
。更具体地说,当N = 10时,我想要这样的东西。

[[ 6.  2.  3.  4.  7.  5.  5.  7.  8.  4.]
 [ 1.  4.  5.  5.  4.  4.  8.  5.  7.  5.]
 [ 7.  3.  8.  8.  3.  8.  7.  3.  6.  7.]
 [ 3.  6.  7.  1.  5.  6.  2.  1.  5.  1.]
 [ 8.  1.  4.  3.  8.  2.  3.  4.  3.  3.]
 [ 5.  8.  1.  7.  1.  3.  6.  8.  1.  6.]
 [ 4.  5.  2.  6.  2.  1.  1.  6.  4.  2.]
 [ 2.  7.  6.  2.  6.  7.  4.  2.  2.  8.]]

为此,我使用以下方法:

import numpy.random
import numpy
def rand_M(N):
    M = numpy.zeros(shape = (8, N))
    for i in range (0, N):
        M[:, i] = numpy.random.choice(8, size = 8, replace = False) + 1 
    return M

实际上,N将为〜1e7。上面的算法在时间上为O(n),当N = 1e3时大约需要0.38秒。因此,N =
1e7的时间约为1小时(即3800秒)。必须有一种更有效的方法。

定时功能

from timeit import Timer 
t = Timer(lambda: rand_M(1000))
print(t.timeit(5))
0.3863314103162543
关注者
0
被浏览
59
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    创建一个指定形状的随机数组,然后沿要保留限制的轴进行排序,从而为我们提供了矢量化且非常有效的解决方案。这将在此基础上smart answer 对MATLAB randomly permuting columns differently。这是实现-

    样品运行-

    In [122]: N = 10
    
    In [123]: np.argsort(np.random.rand(8,N),axis=0)+1
    Out[123]: 
    array([[7, 3, 5, 1, 1, 5, 2, 4, 1, 4],
           [8, 4, 3, 2, 2, 8, 5, 5, 6, 2],
           [1, 2, 4, 6, 5, 4, 4, 3, 4, 7],
           [5, 6, 2, 5, 8, 2, 7, 8, 5, 8],
           [2, 8, 6, 3, 4, 7, 1, 1, 2, 6],
           [6, 7, 7, 8, 6, 6, 3, 2, 7, 3],
           [4, 1, 1, 4, 3, 3, 8, 6, 8, 1],
           [3, 5, 8, 7, 7, 1, 6, 7, 3, 5]], dtype=int64)
    

    运行时测试-

    In [124]: def sortbased_rand8(N):
         ...:     return np.argsort(np.random.rand(8,N),axis=0)+1
         ...: 
         ...: def rand_M(N):
         ...:     M = np.zeros(shape = (8, N))
         ...:     for i in range (0, N):
         ...:         M[:, i] = np.random.choice(8, size = 8, replace = False) + 1 
         ...:     return M
         ...:
    
    In [125]: N = 5000
    
    In [126]: %timeit sortbased_rand8(N)
    100 loops, best of 3: 1.95 ms per loop
    
    In [127]: %timeit rand_M(N)
    1 loops, best of 3: 233 ms per loop
    

    因此,等待 120x 加速!



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看