2017-01-31 9 views
5

In den Scipy Dokumente geschrieben, dass:Lauf np.empty zum zweiten Mal

Die Funktion Nullen ein Array voller Nullen erzeugt, erzeugt die Funktion diejenigen ein Array voll von Einsen und die Funktion erstellt eine leere Array, dessen anfänglicher Inhalt zufällig ist und vom Zustand des Speichers abhängt. Standardmäßig ist der dtype des erstellten Arrays float64.

So war ich diesen Code lautete:

import numpy as np 
np.empty((1,2)) 

Und es ist Rückkehr:

array([[ 6.92892901e-310, 8.42664136e-317]]) 

So ein Zufallszahlen ist es zurückgeben und alle Dinge sind groß.

Aber, als ich diesen Code zum zweiten Mal ausgeführt habe (in dieser Shell), ist es ein Null-Array zurück!

np.empty((1,2)) 
array([[ 0., 0.]]) 

Und hier ist die Frage, warum es Null Array bei der zweiten Zeit (anstelle der Zufallszahl) zurückgibt?

Antwort

3

Es ist nicht zufällig, es hängt davon ab, was in den Bytes im Speicher gespeichert wurde, die Ihr Computer gab NumPy, wenn es etwas Speicherplatz für das Array anfordert. Wenn dort etwas anderes als Nullen sind, dann werden diese mit dem angeforderten D-Typ interpretiert (scheinbar zufällig, aber ein besseres Wort wäre unvorhersehbar).

In Ihrem Beispiel haben Sie das erste Array nicht gespeichert, so dass der Speicher für das erste Array sofort wiederverwendet wurde.

>>> import numpy as np 
>>> print(id(np.empty((20)))) 
2545385324992 
>>> print(id(np.empty((20)))) 
2545385324992 

Jetzt kommt den erstaunlichen Teil: Es Python scheint (oder NumPy oder Ihre OS) Nullen, dass der Speicher, bevor sie es zu NumPy gibt wieder.

Wenn Sie einen größeren Array zu erstellen, als es nicht „Null“ sein wird, weil es von woanders genommen hat:

>>> print(np.empty((1, 2))) 
[[ 1.25757479e-311 1.25757479e-311]] 
>>> print(np.empty((1, 3))) 
[[ 4.94065646e-324 9.88131292e-324 1.25757705e-311]] 
+0

Interessant! Ich hätte nicht erwartet, dass es dieselbe Erinnerung ist. Aber ist dieses Verhalten garantiert? –

+0

@PaulPanzer Ich bin mir fast sicher, dass sowohl das Zero'ing als auch die Wiederverwendung ein Implementierungsdetail ist (also nicht garantiert). Letzteres macht jedoch Sinn, weil es wahrscheinlich effizienter ist, kürzlich frei gewordenen Speicher wiederzuverwenden, wenn genau die gleiche "Größe" erneut angefordert wird, so dass es nicht unwahrscheinlich ist. – MSeifert

+0

Das ist wirklich rätselhaft. Wenn es gute Gründe gibt, den Speicher zum zweiten Mal auf Null zu setzen. Warum zum Teufel sie nicht das erste Mal anwenden? –

1

Der Wortlaut der Dokumente scheint in diesem Fall etwas unglücklich. Sie bedeuten nicht Zufall im Sinne eines richtigen Zufallszahlengenerators. Wenn letzteres das ist, was Sie brauchen, können Sie eine der Funktionen in numpy.random oder scipy.stats verwenden.

Beschreiben numpy.empty ein besseres Wort wäre "undefiniert", was bedeutet, dass der Benutzer keine Annahmen über die anfänglich im Array zurückgegebenen Werte treffen kann. empty ist die günstigste Art, ein Array zu erstellen, wenn Sie wissen, dass Sie den Inhalt sowieso überschreiben werden. Der Computer wird nur etwas Speicher für Sie greifen. Wenn dieser Speicher in dieser Sitzung noch nicht verwendet wurde, wird er zufällig erscheinen. Aber Ihr Computer recycelt auch Speicher.

Ich muss zugeben, ich weiß nicht wirklich, was Speicher sieht recycelt wie nur zwei plausible Möglichkeiten wären

  • es enthält, was das Programm, das es vor der Verwendung geschehen schreiben
  • oder vielleicht das OS hat es aus Sicherheitsgründen mit Nullen überschrieben

Jede Möglichkeit würde erklären, was Sie sehen.

Verwandte Themen