복붙노트

[PYTHON] 모든 고유 한 값을 갖는 2D 배열을 생성하기 위해 임의 선택

PYTHON

모든 고유 한 값을 갖는 2D 배열을 생성하기 위해 임의 선택

그래서 각 행에 고유 한 값이있는 np.random.choice를 사용하여 2 차원 배열을 생성 할 때보다 효율적인 솔루션이 있는지 궁금합니다.

예를 들어, 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 사이에 있어야합니다.

False를 대체 인수로 전달하여이를 달성 할 수 있음을 알고 있습니다. 그러나 나는 행마다 그리고 행렬 전체에 대해서만 할 수는 없습니다. 예를 들어, 나는 이것을 할 수있다 :

>>> 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 루프를 사용하여 해결할 수 있음을 알고 있습니다.

 >>> 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-loops를 사용하지 않고도 해결 방법이 있는지 알고 싶었습니다. (나는 for-loops를 추가하는 것이 1000보다 큰 행을 가진다면 속도가 느려질 수 있다고 가정하고 있습니다.하지만 여러분이 볼 수 있듯이 저는 실제로 발전기를 만들고 있습니다. 결국 효과.)

해결법

  1. ==============================

    1.내가 자주 사용하는 트릭 중 하나는 임의의 배열을 생성하고 argsort를 사용하여 고유 한 인덱스를 필요한 고유 번호로 가져 오는 것입니다. 따라서 우리는 할 수 있습니다 -

    내가 자주 사용하는 트릭 중 하나는 임의의 배열을 생성하고 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
    
  2. from https://stackoverflow.com/questions/45437988/numpy-random-choice-to-produce-a-2d-array-with-all-unique-values by cc-by-sa and MIT license