wake-up-neo.com

So konvertieren Sie ein Numpy 2D-Array mit dem Objekt dtype in ein reguläres 2D-Array von Floats

Als Teil eines breiteren Programms, an dem ich gerade arbeite, habe ich Objektarrays mit Strings, 3D-Koordinaten usw. erhalten, die alle gemischt sind. Ich weiß, dass Objekt-Arrays im Vergleich zu strukturierten Arrays nicht sehr beliebt sind, aber ich hoffe, dies zu umgehen, ohne viele Codes zu ändern.

Nehmen wir an, jede Zeile meines Arrays obj_array (mit N Zeilen) hat das Format 

Single entry/object of obj_array:  ['NAME',[10.0,20.0,30.0],....] 

Jetzt versuche ich, dieses Objektarray zu laden und den 3D-Koordinatenteil zu schneiden. Bis hier funktioniert alles gut mit dem einfachen Fragen, sagen wir mal. 

obj_array[:,[1,2,3]]

Das Ergebnis ist jedoch auch ein Objekt-Array, und ich werde ein Problem haben, da ich ein 2D-Array von Floats mit folgenden Elementen erstellen möchte:

size [N,3] of N rows and 3 entries of X,Y,Z coordinates

Fürs Erste habe ich eine Reihe von Zeilen durchlaufen und jede Zeile einer Zeile eines 2D-Flot-Ziel-Arrays zugewiesen, um das Problem zu umgehen. Ich frage mich, ob es einen besseren Weg mit Array-Konvertierungswerkzeugen von Numpy gibt? Ich habe ein paar Dinge ausprobiert und konnte es nicht umgehen.

Centers   = np.zeros([N,3])

for row in range(obj_array.shape[0]):
    Centers[row,:] = obj_array[row,1]

Vielen Dank

12
Moe

Nasty kleines Problem ... Ich habe mit diesem Spielzeug-Beispiel herumgespielt:

>>> arr = np.array([['one', [1, 2, 3]],['two', [4, 5, 6]]], dtype=np.object)
>>> arr
array([['one', [1, 2, 3]],
       ['two', [4, 5, 6]]], dtype=object)

Meine erste Vermutung war:

>>> np.array(arr[:, 1])
array([[1, 2, 3], [4, 5, 6]], dtype=object)

Aber das behält die Variable object, also vielleicht dann:

>>> np.array(arr[:, 1], dtype=np.float)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: setting an array element with a sequence.

Sie können dies normalerweise folgendermaßen umgehen:

>>> np.array(arr[:, 1], dtype=[('', np.float)]*3).view(np.float).reshape(-1, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: expected a readable buffer object

Nicht hier, was irgendwie rätselhaft war. Anscheinend ist es die Tatsache, dass die Objekte in Ihrem Array Listen sind, die dies auslösen, da das Ersetzen der Listen durch Tupel funktioniert:

>>> np.array([Tuple(j) for j in arr[:, 1]],
...          dtype=[('', np.float)]*3).view(np.float).reshape(-1, 3)
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])

Da es scheinbar keine völlig zufriedenstellende Lösung gibt, ist es wahrscheinlich die einfachste Lösung, mit zu gehen:

>>> np.array(list(arr[:, 1]), dtype=np.float)
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])

Obwohl das nicht sehr effizient sein wird, ist es wahrscheinlich besser, mit etwas wie zu gehen:

>>> np.fromiter((Tuple(j) for j in arr[:, 1]), dtype=[('', np.float)]*3,
...             count=len(arr)).view(np.float).reshape(-1, 3)
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])
10
Jaime

Basierend auf Jaimes Spielzeugbeispiel denke ich, dass Sie dies sehr einfach mit np.vstack() tun können:

arr = np.array([['one', [1, 2, 3]],['two', [4, 5, 6]]], dtype=np.object)
float_arr = np.vstack(arr[:, 1]).astype(np.float)

Dies funktioniert unabhängig davon, ob die 'numerischen' Elemente in Ihrem Objektarray 1D-numpy-Arrays, -Listen oder -Tupel sind.

4
ali_m

Dies funktioniert hervorragend, wenn Sie mit Ihrem Array Arr von einem Objekt in ein Array von Floats konvertieren. Zahlenverarbeitung ist extrem einfach nach. Danke für diesen letzten Beitrag !!!! Ich habe es gerade geändert, um eine beliebige DataFrame-Größe aufzunehmen:

float_arr = np.vstack(arr[:, :]).astype(np.float)
1
Matt

Möglicherweise möchten Sie ein strukturiertes Array verwenden, so dass Sie, wenn Sie auf die Namen und Werte unabhängig zugreifen müssen, dies problemlos tun können. In diesem Beispiel gibt es zwei Datenpunkte:

x = zeros(2, dtype=[('name','S10'), ('value','f4',(3,))])
x[0][0]='item1'
x[1][0]='item2'
y1=x['name']
y2=x['value']

das Ergebnis:

>>> y1
array(['item1', 'item2'], 
      dtype='|S10')
>>> y2
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.]], dtype=float32)

Weitere Einzelheiten finden Sie unter: http://docs.scipy.org/doc/numpy/user/basics.rec.html

1
CT Zhu

Dieses Problem tritt normalerweise auf, wenn Sie über ein Dataset mit unterschiedlichen Typen verfügen, normalerweise über Datumsangaben in der ersten Spalte oder so.

Was ich normalerweise mache, ist das Speichern der Datumsspalte in einer anderen Variablen; und nimm den Rest der "X-Matrix der Features" in X ein. Ich habe also beispielsweise Datumsangaben und X.

Dann wende ich die Konvertierung auf die X-Matrix an als:

X = np.array(list(X[:,:]), dtype=np.float)

Hoffe zu helfen!

1
Pablo Ruiz Ruiz

Dies ist viel schneller, um Ihr Objekt-Array einfach in ein NumPy-Float-Array zu konvertieren: arr=np.array(arr, dtype=[('O', np.float)]).astype(np.float) - Von da an keine Schleife, indizieren Sie es genauso wie Sie es normalerweise bei einem NumPy-Array tun würden. Sie müssten dies jedoch in Abschnitten mit den verschiedenen Datentypen arr[:, 1], arr[:,2] usw. tun. Hatte dasselbe Problem mit einem NumPy-Tuple-Objekt, das von einer C++ DLL- Funktion zurückgegeben wurde - die Konvertierung für 17M-Elemente dauert <2s. 

0
Matt