2017-07-19 15 views
0

16 Gb Maschine gibt nicht genügend Speicherfehler. Ich bezweifle, dass die Umwandlung wirklich vorhanden ist.Numpy inplace dtype Konvertierung

import numpy as np 
x = np.ones(int(1.5e9), dtype=np.int64) # 12 Gb 
x.astype(np.float64, copy=False) # gives out of memory error. 

Wie Speicherkonvertierung in-Place? Ich möchte den Datentyp konvertieren und den Wert beibehalten. Zum Beispiel wird 1.0f ganze Zahl 1.

In-place type conversion of a NumPy array

+0

Wahrscheinlich kann es durch Teile tun. 'y = x.view (dtype = np.float64); y [: 10000] = x [: 10000] .astype (np.float64) ' –

+0

Wie ist die Frage, die Sie verlinken, nicht genug, um Ihr Problem zu lösen? Sieht für mich wie ein exaktes Duplikat aus. – Eric

Antwort

3

Über den copy Parameter:

standardmäßig AsType liefert immer einen neu zugeordneten Array. Wenn auf false gesetzt ist und die Anforderungen dtype, order und subok erfüllt sind, wird stattdessen das Eingabearray einer Kopie zurückgegeben.

So ist es bedingt.

In [540]: x=np.arange(10) 
In [542]: x.dtype 
Out[542]: dtype('int32') 
In [543]: z=x.astype('float32',copy=False) 
In [544]: z 
Out[544]: array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.], dtype=float32) 
In [545]: x.__array_interface__ 
Out[545]: 
{'data': (188221848, False), 
'descr': [('', '<i4')], 
'shape': (10,), 
'strides': None, 
'typestr': '<i4', 
'version': 3} 
In [546]: z.__array_interface__ 
Out[546]: 
{'data': (191273640, False), 
'descr': [('', '<f4')], 
'shape': (10,), 
'strides': None, 
'typestr': '<f4', 
'version': 3} 

z hat einen anderen Speicherort.


Die akzeptierte Antwort in Ihrem Link erscheint mit x, aber mit einer anderen dtype

In [549]: z=x.view('float32') 
In [550]: z[:]=x 
In [551]: z 
Out[551]: array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.], dtype=float32) 
In [552]: x 
Out[552]: 
array([   0, 1065353216, 1073741824, 1077936128, 1082130432, 
     1084227584, 1086324736, 1088421888, 1090519040, 1091567616]) 
In [553]: z 
Out[553]: array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.], dtype=float32) 
In [555]: x.__array_interface__ 
Out[555]: 
{'data': (188221848, False), 
'descr': [('', '<i4')], 
'shape': (10,), 
'strides': None, 
'typestr': '<i4', 
'version': 3} 
In [556]: z.__array_interface__ 
Out[556]: 
{'data': (188221848, False), 
'descr': [('', '<f4')], 
'shape': (10,), 
'strides': None, 
'typestr': '<f4', 
'version': 3} 

Dies funktioniert, weil z Aktien Speicher zu arbeiten. Wenn sie von x zu z kopiert werden, werden sie konvertiert, um dem neuen dtype zu entsprechen. Speicherorte werden beibehalten. Ich kann jedoch nicht garantieren, dass es keinen vorübergehenden Puffer gab.


Falls es nicht klar ist, Umwandlung Form int32 zu float32 erfordert eine Änderung der zugrunde liegenden Bytes. Die Bitdarstellung von Ganzzahlen unterscheidet sich von der von Gleitkommazahlen.

In [594]: np.array(1, 'int32').tobytes() 
Out[594]: b'\x01\x00\x00\x00' 
In [595]: np.array(1, 'float32').tobytes() 
Out[595]: b'\x00\x00\x80?' 
+0

float32 und int32 verwenden beide dieselbe Speichermenge. aber astype macht immernoch neue kopien, was nicht nötig und ineffizient ist ... –

+0

Was hat effizienz damit zu tun? Jeder 4-Byte-Block muss den gleichen Konvertierungsprozess durchlaufen. Ob es an denselben oder an einen anderen Speicherort zurückgeschrieben wird, sollte keinen großen Unterschied in der Geschwindigkeit machen. – hpaulj

+0

Ich denke, Kopieren ist langsamer als die Operation an Ort und Stelle zu tun, weil CPU nicht eine zusätzliche Cache-Zeile des Speichers lesen/schreiben müssen. Prefetch sollte die Speicherlatenz maskieren. Ich weiß nicht, ob Prefetch ohne dieses Kopieren besser funktioniert. https://stackoverflow.com/questions/3928995/how-do-cache-lines-work Making Kopie ist sicher weniger effizient. –

Verwandte Themen