Folgendes importiert NumPy und legt den Samen fest.
import numpy as np
np.random.seed(42)
Ich bin jedoch nicht daran interessiert, den Samen zu setzen, sondern ihn mehr zu lesen. random.get_state()
scheint den Samen nicht zu enthalten. Die Dokumentation zeigt keine offensichtliche Antwort.
Wie rufe ich den aktuellen Ausgangswert von numpy.random
ab, vorausgesetzt, ich habe ihn nicht manuell festgelegt
Ich möchte den aktuellen Samen verwenden, um ihn für die nächste Iteration eines Prozesses zu übernehmen.
Die kurze Antwort ist, dass Sie einfach nicht können (zumindest nicht generell).
Der von numpy verwendete Mersenne Twister RNG hat 219937-1 mögliche interne Zustände, während eine einzelne 64-Bit-Ganzzahl nur 2 hat64 mögliche Werte. Es ist daher unmöglich, jeden RNG-Status einem eindeutigen Ganzzahl-Seed zuzuordnen.
Sie can können den internen Status des RNG direkt mit np.random.get_state
und np.random.set_state
abrufen und setzen. Die Ausgabe von get_state
ist ein Tuple, dessen zweites Element ein (624,)
-Array von 32-Bit-Ganzzahlen ist. Dieses Array hat mehr als genug Bits, um jeden möglichen internen Zustand des RNG darzustellen (2624 * 32 > 219937-1).
Das von get_state
zurückgegebene Tuple kann wie ein Seed verwendet werden, um reproduzierbare Folgen von Zufallszahlen zu erzeugen. Zum Beispiel:
import numpy as np
# randomly initialize the RNG from some platform-dependent source of entropy
np.random.seed(None)
# get the initial state of the RNG
st0 = np.random.get_state()
# draw some random numbers
print(np.random.randint(0, 100, 10))
# [ 8 76 76 33 77 26 3 1 68 21]
# set the state back to what it was originally
np.random.set_state(st0)
# draw again
print(np.random.randint(0, 100, 10))
# [ 8 76 76 33 77 26 3 1 68 21]
Diese Antwort wurde bearbeitet, nachdem ich weitere Einzelheiten zu dem vorliegenden Problem herausgefunden hatte. Ich hoffe, dass dies in der jetzigen Form eine gute Erklärung für die Antwort von ALi_m und eine wichtige Korrektur für die Antwort von Dong Justin darstellt.
Das sind meine Erkenntnisse:
np.random.seed(X)
eingestellt haben, können Sie ihn mit np.random.get_state()[1][0]
wiederfinden .Die Ausgabe der folgenden Codeabschnitte zeigt, warum beide Anweisungen korrekt sind.
Anweisung 1 - Sie können den zufälligen Samen mit np.random.get_state()[1][0]
finden.
Wenn Sie den Zufallsstartwert mit np.random.seed(123)
festlegen, können Sie den Zufallsstatus als Tupel mit state = np.random.get_state()
abrufen. Unten sehen Sie sich state
genauer an (ich verwende den Variablen-Explorer in Spyder). Ich verwende einen Screenshot, da die Verwendung von print(state)
Ihre Konsole aufgrund der Größe des Arrays im zweiten Element des Tupels überfluten wird.
Sie können leicht 123
Als die erste Zahl in dem im zweiten Element enthaltenen Array sehen. Und mit seed = np.random.get_state()[1][0]
erhalten Sie 123
. Perfekt? Nicht ganz, weil:
Statement 2 - Es wird Ihnen jedoch wenig nützen:
Dies scheint jedoch zunächst nicht der Fall zu sein, da Sie könntenp.random.seed(123)
verwenden, dieselbe Zahl mit seed = np.random.get_state()[1][0]
abrufen und den Startwert mit np.random.seed(444)
und setzen Sie es dann (scheinbar) mit np.random.seed(seed)
auf das Szenario 123
zurück. Aber dann wüsstest du schon vorher, wie dein zufälliger Startwert lautete , also musst du es nicht so machen. Der nächste Codeabschnitt zeigt auch, dass Sie mit np.random.get_state()[1][0]
nicht die erste Zahl eines zufälligen Zustands nehmen können und damit rechnen, dass genau dieses Szenario erneut erstellt wird. Beachten Sie, dass Sie höchstwahrscheinlich Ihren Kernel herunterfahren und neu starten müssen vollständig (oder np.random.seed(None)
aufrufen müssen, um dies zu sehen.
Das folgende Snippet verwendet np.random.randint()
, um 5 zufällige Ganzzahlen zwischen -10 und 10 zu generieren und einige Informationen über den Prozess zu speichern:
Snippet 1
# 1. Imports
import pandas as pd
import numpy as np
# 2. set random seed
#seedSet = None
seedSet = 123
np.random.seed(seedSet)
# 3. describe random state
state = np.random.get_state()
state5 = np.random.get_state()[1][:5]
seedState = np.random.get_state()[1][0]
# 4. generate random numbers
random = np.random.randint(-10, 10, size = 5)
# 5. organize and present findings
df = pd.DataFrame.from_dict({'seedSet':seedSet, 'seedState':seedState, 'state':state, 'random':random})
print(df)
Beachten Sie, dass die Spalte mit dem Namen seedState
der ersten Zahl unter state
entspricht. Ich hätte es als eigenständige Nummer ausdrucken können, aber ich wollte alles am selben Ort aufbewahren. Beachten Sie auch, dass seedSet = 123
Und np.random.seed(seedSet)
bisher auskommentiert wurden. Und weil kein zufälliger Startwert festgelegt wurde, weichen Ihre Zahlen von meinen ab. Aber darauf kommt es hier nicht an, sondern auf die interne Konsistenz Ihrer Ergebnisse:
Ausgang 1:
random seedSet seedState state
0 2 None 1558056443 1558056443
1 -1 None 1558056443 1808451632
2 4 None 1558056443 730968006
3 -4 None 1558056443 3568749506
4 -6 None 1558056443 3809593045
In diesem speziellen Fall ist seed = np.random.get_state()[1][0]
gleich 1558056443
. Und wenn Sie der Logik von Dong Justins Antwort (und meiner eigenen Antwort vor dieser Bearbeitung) folgen, können Sie den Zufallsstartwert mit np.random.seed(1558056443)
festlegen und denselben Zufallsstatus erhalten. Das nächste Snippet zeigt, dass Sie nicht können:
Snippet 2
# 1. Imports
import pandas as pd
import numpy as np
# 2. set random seed
#seedSet = None
seedSet = 1558056443
np.random.seed(seedSet)
# 3. describe random state
#state = np.random.get_state()
state = np.random.get_state()[1][:5]
seedState = np.random.get_state()[1][0]
# 4. generate random numbers
random = np.random.randint(-10, 10, size = 5)
# 5. organize and present findings
df = pd.DataFrame.from_dict({'seedSet':seedSet, 'seedState':seedState, 'state':state, 'random':random})
print(df)
Ausgang 2:
random seedSet seedState state
0 8 1558056443 1558056443 1558056443
1 3 1558056443 1558056443 1391218083
2 7 1558056443 1558056443 2754892524
3 -8 1558056443 1558056443 1971852777
4 4 1558056443 1558056443 2881604748
Sieh den Unterschied? np.random.get_state()[1][0]
ist für Ausgang 1 und Ausgang 2 identisch, der Rest der Ausgabe ist jedoch nicht identisch (am wichtigsten ist, dass die Zufallszahlen nicht identisch sind). Also, wie ALi_m bereits klar festgestellt hat:
Es ist daher unmöglich, jeden RNG-Zustand einem eindeutigen Integer-Startwert zuzuordnen.
Überprüfen Sie das erste Element des Arrays, das von np.random.get_state()
zurückgegeben wird. Es scheint mir der zufällige Samen.