동일한 임의의 numpy 배열을 일관되게 생성


89

다른 개발자가 -1,0 또는 1의 값으로 np 배열 (100,2000)을 반환하는 코드 조각을 완료하기를 기다리고 있습니다.

그 동안 나는 개발 및 테스트를 앞당길 수 있도록 동일한 특성의 배열을 무작위로 만들고 싶습니다. 문제는 무작위로 생성 된이 배열이 매번 동일하기를 원하므로 프로세스를 다시 실행할 때마다 값을 계속 변경하는 배열에 대해 테스트하지 않습니다.

이렇게 내 배열을 만들 수 있지만 매번 동일하게 만들 수있는 방법이 있습니다. 나는 물건을 피클하고 피클을 풀 수 있지만 다른 방법이 있는지 궁금합니다.

r = np.random.randint(3, size=(100, 2000)) - 1

답변:


84

난수 생성기에 고정 값을 시드하기 만하면됩니다.

numpy.random.seed(42)

이렇게하면 항상 동일한 난수 시퀀스를 얻을 수 있습니다.

이 함수는 전역 기본 난수 생성기를 시드하고의 함수에 대한 모든 호출 numpy.random은 해당 상태를 사용하고 변경합니다. 이것은 많은 간단한 사용 사례에 적합하지만 전역 상태가 가져 오는 모든 문제가있는 전역 상태의 한 형태입니다. 더 깨끗한 솔루션은 아래 Robert Kern의 답변을 참조하십시오.


43
numpy.random.seed()내가주의를 기울이지 않았을 때 누군가 기능에 몰래 들어갔다 . :-) 의도적으로 원래 모듈에서 제외했습니다. 나는 사람들이 그들 자신의 인스턴스를 사용하고 RandomState그 물체를 주변에 전달하는 것이 좋습니다 .
Robert Kern

6
Robert는 numpy의 주요 기여자입니다. 그의 의견에 무게를 두어야한다고 생각합니다.
더 이상 사용되지 않음

11
@deprecated : Robert의 작업에 감사하지만 그의 작업은 추천에 대한 근거를 제공하는 대신 사용할 수 없습니다. 또한의 사용 numpy.random.seed()이 권장되지 않는 경우 문서에 언급되어야합니다 . 분명히 NumPy의 다른 기여자들은 Robert의 의견을 공유하지 않습니다. 전혀 공격을 의도하지 않았고, 나는 단지 궁금합니다.
Sven Marnach

13
이것은 Python 표준 라이브러리에서 객체를 random.seed사용하는 것과 사용하는 것과 동일 random.Random합니다. random.seed또는 을 사용하는 경우 코드와 호출중인 코드 또는 동일한 세션에서 실행되는 코드 모두에서 모든 임의 인스턴스를 numpy.random.seed시드 합니다 . 그런 것들이 실제로 무작위적인 것에 의존한다면, 문제가 발생하기 시작합니다. 랜덤 시드를 설정하는 코드를 배포하면 보안 취약점이 발생할 수 있습니다.
asmeurer 2014 년

3
@asmeurer 보안 목적으로 의사 난수 생성기를 사용하는 사람은 누구나 자신이 무엇을하는지 모를 것입니다.
JAB

191

numpy.random.RandomState()선택한 시드로 자신의 인스턴스를 만듭니다 . numpy.random.seed()자신의 RandomState인스턴스 를 전달할 수없는 유연성이없는 라이브러리를 해결 하는 경우를 제외하고는 사용하지 마십시오 .

[~]
|1> from numpy.random import RandomState

[~]
|2> prng = RandomState(1234567890)

[~]
|3> prng.randint(-1, 2, size=10)
array([ 1,  1, -1,  0,  0, -1,  1,  0, -1, -1])

[~]
|4> prng2 = RandomState(1234567890)

[~]
|5> prng2.randint(-1, 2, size=10)
array([ 1,  1, -1,  0,  0, -1,  1,  0, -1, -1])

7
추천에 대한 근거가 있습니까? 뭐가 잘못 numpy.random.seed()됐나요? 스레드로부터 안전하지는 않지만 스레드 안전성이 필요하지 않으면 정말 편리합니다.
Sven Marnach 2011

52
대부분 좋은 습관을 형성하는 것입니다. 지금은 독립 스트림이 필요하지 않을 수 있지만 지금부터 6 개월 후 Sven이 필요할 수 있습니다. 에서 직접 메서드를 사용하도록 라이브러리를 작성하는 경우 numpy.random나중에 독립 스트림을 만들 수 없습니다. PRNG 스트림을 제어 할 목적으로 라이브러리를 작성하는 것도 더 쉽습니다. 라이브러리에 들어가는 방법은 항상 여러 가지가 있으며 각 방법은 시드를 제어 할 수 있어야합니다. PRNG 객체를 전달하는 것이 numpy.random.seed(). 불행히도이 주석 상자는 너무 짧아 더 많은 예제를 포함 할 수 없습니다. :-)
Robert Kern

25
Robert의 이론적 근거를 설명하는 또 다른 방법 : numpy.random.seed를 사용하면 전역 변수를 사용하여 PRNG 상태를 유지하고 전역 변수가 잘못된 것과 동일한 표준 이유가 여기에 적용됩니다.
Robie Basak

9
PRNG가 독립되도록하려면 아무것도 시드하지 마십시오. numpy.random.RandomState()인수없이 사용하십시오 . 이렇게하면 이러한 작업에 대해 운영 체제 기능에서 가져온 고유 한 값으로 상태가 시드됩니다 ( /dev/urandomUNIX 컴퓨터 및 Windows에 해당). 이 ( numpy.random.RandomState(1234567890)가) 작동하지 않는 경우 입력 한 내용과받은 오류 메시지를 정확히 보여주세요.
Robert Kern 2012 년

5
좋은 생각이 아닙니다. numpy.random.RandomState()최상의 결과를 위해 인수없이 사용하십시오 .
Robert Kern 2014 년

3

임의 상태에 의존하는 다른 함수를 사용하는 경우 전체 시드를 설정할 수는 없지만 대신 임의의 숫자 목록을 생성하고 시드를 함수의 매개 변수로 설정하는 함수를 만들어야합니다. 이것은 코드의 다른 임의 생성기를 방해하지 않습니다.

# Random states
def get_states(random_state, low, high, size):
    rs = np.random.RandomState(random_state)
    states = rs.randint(low=low, high=high, size=size)
    return states

# Call function
states = get_states(random_state=42, low=2, high=28347, size=25)

3

랜덤 생성기의 시드가 무엇인지, 코드에서 언제 / 어떻게 설정되는지 이해하는 것이 중요합니다 (시드의 수학적 의미에 대한 좋은 설명은 여기 에서 확인 하십시오 ).

이를 위해 다음을 수행하여 시드를 설정해야합니다.

random_state = np.random.RandomState(seed=your_favorite_seed_value)

그런 다음 np.random이 아닌 random_state에서 난수를 생성하는 것이 중요합니다. 즉, 다음을 수행해야합니다.

random_state.randint(...)

대신에

np.random.randint(...) 

RandomState ()의 새 인스턴스를 만들고 기본적으로 컴퓨터 내부 시계를 사용하여 시드를 설정합니다.


2

명확하지 않은 경우 @Robert Kern 답변과 관련하여 뭔가를 명확히하고 싶습니다. 를 사용하더라도 RandomStateRobert의 예제와 같이 numpy random 메서드를 호출 할 때마다 초기화해야합니다. 그렇지 않으면 다음과 같은 결과를 얻을 수 있습니다.

Python 3.6.9 |Anaconda, Inc.| (default, Jul 30 2019, 19:07:31) 
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> prng = np.random.RandomState(2019)
>>> prng.randint(-1, 2, size=10)
array([-1,  1,  0, -1,  1,  1, -1,  0, -1,  1])
>>> prng.randint(-1, 2, size=10)
array([-1, -1, -1,  0, -1, -1,  1,  0, -1, -1])
>>> prng.randint(-1, 2, size=10)
array([ 0, -1, -1,  0,  1,  1, -1,  1, -1,  1])
>>> prng.randint(-1, 2, size=10)
array([ 1,  1,  0,  0,  0, -1,  1,  1,  0, -1])
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.