大量选择以产生具有所有唯一值的2D数组

发布于 2021-01-29 15:04:04

因此,我想知道是否存在一种更有效的解决方案,该方法使用np.random.choice每行具有唯一值的位置生成二维数组。

例如,对于具有shape的数组(3,4),我们期望输出为:

# Expected output given a shape (3,4)
array([[0, 1, 3, 2],
       [2, 3, 1, 0],
       [1, 3, 2, 0]])

这意味着每行的值在列数方面必须是唯一的。因此,对于中的每一行out,整数应仅介于0到3之间。

我知道,我可以通过传递实现它Falsereplace论据。但是我只能为每一行而不是整个矩阵执行此操作。例如,我可以这样做:

>>> np.random.choice(4, size=(1,4), replace=False)
array([[0,2,3,1]])

但是当我尝试这样做时:

>>> np.random.choice(4, size=(3,4), replace=False)

我收到这样的错误:

 File "<stdin>", line 1, in <module>
 File "mtrand.pyx", line 1150, in mtrand.RandomState.choice 
 (numpy\random\mtrand\mtrand.c:18113)
 ValueError: Cannot take a larger sample than population when 
 'replace=False'

我认为这是因为3 x 4 = 12由于矩阵的大小,它试图绘制样本而不进行替换,但我只给出了极限4

我知道我可以通过使用解决for-loop

 >>> a = (np.random.choice(4,size=4,replace=False) for _ in range(3))
 >>> np.vstack(a)
 array([[3, 1, 2, 0],
        [1, 2, 0, 3],
        [2, 0, 3, 1]])

但是我想知道是否有一种不使用任何for循环的解决方法?(我有点假设,如果我的行数大于1000,添加for循环可能会使速度变慢。但是正如您所看到的,我实际上是在创建生成器,a因此我也不知道它是否有效果毕竟。)

关注者
0
被浏览
236
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    我经常使用的一个技巧是生成一个随机数组,并argsort用于获取唯一索引作为所需的唯一数字。因此,我们可以-

    def random_choice_noreplace(m,n, axis=-1):
        # m, n are the number of rows, cols of output
        return np.random.rand(m,n).argsort(axis=axis)
    

    样品运行-

    In [98]: random_choice_noreplace(3,7)
    Out[98]: 
    array([[0, 4, 3, 2, 6, 5, 1],
           [5, 1, 4, 6, 0, 2, 3],
           [6, 1, 0, 4, 5, 3, 2]])
    
    In [99]: random_choice_noreplace(5,7, axis=0) # unique nums along cols
    Out[99]: 
    array([[0, 2, 4, 4, 1, 0, 2],
           [1, 4, 3, 2, 4, 1, 3],
           [3, 1, 1, 3, 2, 3, 0],
           [2, 3, 0, 0, 0, 2, 4],
           [4, 0, 2, 1, 3, 4, 1]])
    

    运行时测试-

    # Original approach
    def loopy_app(m,n):
        a = (np.random.choice(n,size=n,replace=False) for _ in range(m))
        return np.vstack(a)
    

    时间-

    In [108]: %timeit loopy_app(1000,100)
    10 loops, best of 3: 20.6 ms per loop
    
    In [109]: %timeit random_choice_noreplace(1000,100)
    100 loops, best of 3: 3.66 ms per loop
    


知识点
面圈网VIP题库

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

去下载看看