2017-02-01 3 views
5

zugreifen Ich muss eine Klasse erstellen, die einen Zufallsgenerator (d. H. Ein numpy.random.RandomState Objekt) als Parameter übernimmt. Wenn dieses Argument nicht angegeben ist, möchte ich es dem Zufallsgenerator zuweisen, den numpy verwendet, wenn wir numpy.random.<random-method> ausführen. Wie greife ich auf diesen globalen Generator zu? Momentan mache ich das, indem ich das Modul-Objekt einfach als Zufallsgenerator (da sie Methoden teilen/Duck-Typisierung) zuweisen. Dies verursacht jedoch Probleme beim Beizen (das Modulobjekt kann nicht beigemischt werden) und beim Tiefkopieren. Ich möchte das RandomState Objekt hinter numpy.randomWie numpy Standard globalen Zufallszahlengenerator

PS verwenden: Ich verwende Python-3,4

+0

@ user2357112 Im Allgemeinen würde ich nicht erwarten, dass Module picklable sein, da sie alle Arten von unpicklable Objekten (C-Erweiterungen, Lambda-Ausdrücke, Verschlüssen etc.) enthalten können –

+0

@ali_m: Ich konnte Ich habe geschworen, sie waren mit Namen und Pick-up-Pickled, genau wie Funktionen und Klassen, aber anscheinend nicht. Wenn ich es versuche, bekomme ich auch einen Fehler. – user2357112

+0

@ user2357112 Es gibt nichts * intrinsisch * unpicklable über Module. Solange sie nur einfügbare Objekte enthalten, geht es Ihnen gut, aber für die meisten nicht-trivialen Module ist dies nicht der Fall. Zum Beispiel ist numpy mit nicht wiederholbaren C-Erweiterungen gespickt. –

Antwort

2

Neben was kazemakase schon sagt, wir Vorteil aus der Tatsache ziehen, dass Modul-Level-Funktionen wie numpy.random.random wirklich Methoden einer versteckten numpy.random.RandomState sind durch die __self__ direkt von einem dieser Methoden ziehen:

numpy_default_rng = numpy.random.random.__self__ 
+0

Tatsächlich scheint dies zukunftssicherer zu sein als direkt mit _rand. Danke, ich wusste nicht, dass es so etwas wie ein Attribut "__self__" gibt. – Atimaharjun

2

numpy.random Importe * von numpy.random.mtrand, die ein Erweiterungsmodul in Cython geschrieben ist. Die source code zeigt, dass der globale Status in der Variablen _rand gespeichert ist. Diese Variable is not imported in den numpy.random Bereich, aber Sie können es direkt von MTRAND erhalten.

import numpy as np 
from numpy.random.mtrand import _rand as global_randstate 

np.random.seed(42) 
print(np.random.rand()) 
# 0.3745401188473625 

np.random.RandomState().seed(42) # Different object, does not influence global state 
print(np.random.rand()) 
# 0.9507143064099162 

global_randstate.seed(42) # this changes the global state 
print(np.random.rand()) 
# 0.3745401188473625 
+0

Das habe ich beschlossen, als ich die Frage gepostet habe, aber ich hatte gehofft, dass es eine Möglichkeit gäbe, dies zu erreichen, ohne versteckte Mitglieder zu finden (für Zukunftssicherheit). Die Methode von User2357112 scheint das zu ermöglichen. Also habe ich das als Antwort gewählt. Danke für die Antwort trotzdem. – Atimaharjun

0

Ich weiß nicht, wie Sie auf den globalen Status zugreifen. Sie können jedoch ein RandomState-Objekt verwenden und es weitergeben. Zufällige Verteilungen sind daran angehängt, daher nennt man sie Methoden.

Beispiel:

import numpy as np 

def computation(parameter, rs): 
    return parameter*np.sum(rs.uniform(size=5)-0.5) 

my_state = np.random.RandomState(seed=3) 

print(computation(3, my_state)) 
Verwandte Themen