numpy의 반복되지 않는 난수


88

numpy에서 반복되지 않는 난수를 어떻게 생성 할 수 있습니까?

list = np.random.random_integers(20,size=(10))

"비 반복적"이란 무엇을 의미합니까? 난수의 시퀀스가 ​​결코 재발하지 않는다는 것? 난수 생성기의 상태가 컴퓨터의 유한 메모리에 맞아야하기 때문에 불가능합니다. 아니면 단일 숫자가 두 번 발생하지 않는다는 의미입니까?
Sven Marnach

5
비 반복은 중복이없는 목록이 있음을 의미합니다.
다항식

2
무작위 순열이 필요한가요? docs.scipy.org/doc/numpy/reference/generated/…
cyborg

답변:


106

numpy.random.Generator.choicereplace대체하지 않고 샘플에 대한 인수를 제공합니다 .

from numpy.random import default_rng

rng = default_rng()
numbers = rng.choice(20, size=10, replace=False)

GeneratorAPI 없이 1.17 이전 NumPy 를 사용 random.sample()하는 경우 표준 라이브러리에서 사용할 수 있습니다 .

print(random.sample(range(20), 10))

사용 numpy.random.shuffle()및 슬라이스도 가능하지만 효율성이 떨어집니다.

a = numpy.arange(20)
numpy.random.shuffle(a)
print a[:10]

거기이기도 replace기존의 인수 numpy.random.choice기능은, 그러나 그것의 사용은 권장되지 않도록이 인수로 인해 난수 스트림 안정성 보장에 비효율적으로하고 비효율적 인 왼쪽으로 구현되었습니다. (기본적으로 내부적으로 셔플 및 슬라이스 작업을 수행합니다.)


1
print random.sample (range (20), 10)은 파이썬 2.6에서 작동하지 않습니까?!
Academia

당신은 import random?
Sven Marnach

문제는 잘못된 Pydev 구성 때문이었습니다. Thks
Academia

1
내 n이 20이 아니라 1000000과 같지만 10 개의 고유 번호 만 필요하면 메모리 효율적인 접근 방식이 있습니까?
mrgloom

2
@mrgloom Python 3에서는 객체가 시작, 중지 및 단계 값을 저장하는 작은 래퍼 일뿐 정수의 전체 목록을 생성하지 않기 때문에 random.sample(range(n), 10))매우 큰 경우에도 효율적 입니다. 파이썬이, 당신은 대체 할 수 와 비슷한 동작을 얻을 수 있습니다. nrangerangexrange
Sven Marnach

107

지금은 numpy.random.sample작동하지 않는 것 같습니다. 이게 내 방법이야:

import numpy as np
np.random.choice(range(20), 10, replace=False)

25
대신에 range(n)(또는 그 arange(n)중 첫 번째 인수 등) choice, 그냥 통과 동등 nchoice(20, 10, replace=False).
조쉬 보데

1
참고 np.random.choice(a, size, replace=False)대형 매우 느리게 a- 내 컴퓨터에서은을 위해 약 30 밀리 1M를 =.
Matthew Rahtz

3
대량 n사용시 시간 및 메모리 문제를 방지하려면 numpy.random.Generator.choice(numpy v1.17부터 시작)
benbo

1
내가 본 주요 단점은 np.random.choice에 축 매개 변수가 없다는 것입니다.-> 1d 배열에만 해당됩니다.
Moosefeather

3

몇 년 후, 10000 ^ 2 (Numpy 1.8.1, imac 2.7GHz) 중 40000을 선택하는 시간이 있습니다.

import random
import numpy as np

n = 10000
k = 4
np.random.seed( 0 )

%timeit np.random.choice( n**2, k * n, replace=True )  # 536 µs ± 1.58 µs
%timeit np.random.choice( n**2, k * n, replace=False ) # 6.1 s ± 9.91 ms

# https://docs.scipy.org/doc/numpy/reference/random/index.html
randomstate = np.random.default_rng( 0 )
%timeit randomstate.choice( n**2, k * n, replace=False, shuffle=False )  # 766 µs ± 2.18 µs
%timeit randomstate.choice( n**2, k * n, replace=False, shuffle=True )   # 1.05 ms ± 1.41 µs

%timeit random.sample( range( n**2 ), k * n )          # 47.3 ms ± 134 µs

(왜 10000 ^ 2 중에서 40000을 선택합니까? 큰 scipy.sparse.random 행렬 을 생성하려면 np.random.choice( replace=False )-scipy 1.4.1 사용 , slooooow.)

numpy.random 사람들에게 모자 팁.


1

정렬하여 얻을 수도 있습니다.

random_numbers = np.random.random([num_samples, max_int])
samples = np.argsort(random_numbers, axis=1)

-3

필요한 범위의 숫자를 포함하는 배열을 생성 한 다음 임의의 숫자를 배열의 0 번째 요소와 반복적으로 교체하여 섞습니다. 이것은 중복 값을 포함하지 않는 임의의 시퀀스를 생성합니다.


2
결과 랜덤 시퀀스의 또 다른 속성은 특별히 랜덤하지 않다는 것입니다 .
Sven Marnach

@SvenMarnach-대부분의 경우, 그것은 충분히 임의적입니다. 그는 더 무작위로 원할 경우 이중 무작위 접근 방식을 사용할 수 있습니다.
다항식

이것은 무의미합니다. OP는 라이브러리 호출을 사용하여 올바르게 수행 할 수 있습니다. 사용하기 쉽고 빠르게 실행되며 사용자 정의 버전보다 더 읽기 쉽습니다. 올바른 알고리즘을 사용하는 데 아무런 단점이 없을 때 "충분히 임의적"이기 때문에 여기에서 잘못된 알고리즘을 사용해야하는 이유를 생각할 수 없습니다.
Sven Marnach

@SvenMarnach-충분합니다. 나는 numpy를 모르기 때문에 잠재적 인 해결책을 제공하고있었습니다.
다항식
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.