Crea costantemente lo stesso array numpy casuale


89

Sto aspettando che un altro sviluppatore finisca un pezzo di codice che restituirà un array np di forma (100,2000) con valori di -1,0 o 1.

Nel frattempo, voglio creare in modo casuale un array delle stesse caratteristiche in modo da poter ottenere un vantaggio sul mio sviluppo e test. Il fatto è che voglio che questo array creato in modo casuale sia lo stesso ogni volta, in modo da non testare un array che continua a cambiare il suo valore ogni volta che riesco a eseguire il mio processo.

Posso creare il mio array in questo modo, ma c'è un modo per crearlo in modo che sia lo stesso ogni volta. Posso mettere in salamoia l'oggetto e rimuoverlo, ma chiedendomi se c'è un altro modo.

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

Risposte:


84

Basta seminare il generatore di numeri casuali con un valore fisso, ad es

numpy.random.seed(42)

In questo modo, otterrai sempre la stessa sequenza di numeri casuali.


43
Qualcuno si è intrufolato nella numpy.random.seed()funzione quando non stavo prestando attenzione. :-) L'ho volutamente lasciato fuori dal modulo originale. Raccomando alle persone di utilizzare le proprie istanze RandomStatee di passare questi oggetti.
Robert Kern

6
Robert è uno dei principali contributori a numpy. Penso che dovremmo dare un certo peso alla sua opinione.
obsoleto

10
@deprecated: sono grato per il lavoro di Robert, ma il suo lavoro non è un sostituto per dare una motivazione alla raccomandazione. Inoltre, se l'uso di numpy.random.seed()è scoraggiato, questo dovrebbe essere menzionato nella documentazione . Apparentemente, altri collaboratori di NumPy non condividono l'opinione di Robert. Nessuna offesa, sono solo curiosa.
Sven Marnach

13
È lo stesso che usare random.seedo usare un random.Randomoggetto nella libreria standard di Python. Se utilizzi random.seedo numpy.random.seed, stai eseguendo il seeding di tutte le istanze casuali, sia nel codice che in qualsiasi codice che stai chiamando o in qualsiasi codice eseguito nella stessa sessione della tua. Se queste cose dipendono dal fatto che quelle cose sono effettivamente casuali, allora inizi a incorrere in problemi. Se distribuisci codice che imposta il seme casuale, puoi introdurre una vulnerabilità di sicurezza.
asmeurer

3
@asmeurer Chiunque utilizzi un generatore di numeri pseudocasuali per motivi di sicurezza probabilmente non sa cosa sta facendo.
JAB

191

Crea la tua istanza di numpy.random.RandomState()con il seme scelto. Non utilizzare numpy.random.seed()tranne per aggirare le librerie inflessibili che non ti consentono di passare la tua RandomStateistanza.

[~]
|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
Hai qualche logica per la tua raccomandazione? Cosa c'è che non va numpy.random.seed()? So che non è thread-safe, ma è davvero comodo se non hai bisogno di thread-safety.
Sven Marnach

52
È principalmente per formare buone abitudini. Potresti non aver bisogno di stream indipendenti ora, ma Sven-6-months-from-now potrebbe. Se scrivi le tue librerie per utilizzare i metodi direttamente da numpy.random, non puoi creare flussi indipendenti in seguito. È anche più facile scrivere librerie con l'intenzione di controllare i flussi PRNG. Esistono sempre più modi per accedere alla tua libreria e ognuno di essi dovrebbe avere un modo per controllare il seme. Passare in giro gli oggetti PRNG è un modo più pulito di farlo piuttosto che fare affidamento numpy.random.seed(). Sfortunatamente, questa casella di commento è troppo breve per contenere altri esempi. :-)
Robert Kern

25
Un altro modo per descrivere la logica di Robert: usare numpy.random.seed usa una variabile globale per mantenere lo stato PRNG, e qui si applicano le stesse ragioni standard per cui le variabili globali non sono corrette.
Robie Basak

9
Se vuoi che i PRNG siano indipendenti, non seminarli con nulla. Basta usare numpy.random.RandomState()senza argomenti. In questo modo lo stato verrà seminato con valori univoci estratti dalle funzionalità del sistema operativo per tali cose ( /dev/urandomsu macchine UNIX e l'equivalente Windows lì). Se numpy.random.RandomState(1234567890)non funziona per te, mostra esattamente cosa hai digitato e esattamente il messaggio di errore che hai ricevuto.
Robert Kern

5
Non è una buona idea. Utilizzare numpy.random.RandomState()senza argomenti per i migliori risultati.
Robert Kern

3

Se stai usando altre funzioni che si basano su uno stato casuale, non puoi semplicemente impostare e seme generale, ma dovresti invece creare una funzione per generare il tuo elenco casuale di numeri e impostare il seme come parametro della funzione. Questo non disturberà nessun altro generatore casuale nel codice:

# 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

È importante capire qual è il seme di un generatore casuale e quando / come è impostato nel codice (controlla ad esempio qui per una bella spiegazione del significato matematico del seme).

Per questo è necessario impostare il seme facendo:

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

È quindi importante generare i numeri casuali da random_state e non da np.random. Cioè dovresti fare:

random_state.randint(...)

invece di

np.random.randint(...) 

che creerà una nuova istanza di RandomState () e fondamentalmente utilizzerà l'orologio interno del computer per impostare il seme.


2

Voglio solo chiarire qualcosa riguardo alla risposta di @Robert Kern nel caso in cui non fosse chiaro. Anche se usi il, RandomStatedovresti inizializzarlo ogni volta che chiami un metodo casuale numpy come nell'esempio di Robert, altrimenti otterrai i seguenti risultati.

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])
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.