Objektarray unter verschiedenen dtype anzeigen

Oct 05 2020

Ich möchte ein Objektarray mit einem dtype anzeigen, der ganze Zeilen kapselt:

data = np.array([['a', '1'], ['a', 'z'], ['b', 'a']], dtype=object)
dt = np.dtype([('x', object), ('y', object)])
data.view(dt)

Ich bekomme einen Fehler:

TypeError: Cannot change data-type for object array.

Ich habe folgende Problemumgehungen versucht:

dt2 = np.dtype([('x', np.object, 2)])
data.view()
data.view(np.uint8).view(dt)
data.view(np.void).view(dt)

Alle Fälle führen zum gleichen Fehler. Gibt es eine Möglichkeit, ein Objektarray mit einem anderen dtype anzuzeigen?

Ich habe auch einen allgemeineren Ansatz ausprobiert (dies dient als Referenz, da er funktional mit dem oben gezeigten identisch ist):

dt = np.dtype(','.join(data.dtype.char * data.shape[1]))
dt2 = np.dtype([('x', data.dtype, data.shape[1])])

Antworten

2 MadPhysicist Oct 05 2020 at 21:40

Es scheint, dass Sie immer eine Ansicht eines Puffers erzwingen können, indem Sie Folgendes verwenden np.array:

view = np.array(data, dtype=dt, copy=not data.flags['C_CONTIGUOUS'])

Obwohl dies ein schneller und schmutziger Ansatz ist, werden die Daten in diesem Fall kopiert und dt2nicht richtig angewendet:

>>> print(view.base)
None
>>> np.array(data, dtype=dt2, copy=not data.flags['C_CONTIGUOUS'])
array([[(['a', 'a'],), (['1', '1'],)],
       [(['a', 'a'],), (['z', 'z'],)],
       [(['b', 'b'],), (['a', 'a'],)]], dtype=[('x', 'O', (2,))])

Für einen korrekteren Ansatz (unter Umständen) können Sie den Rohkonstruktor np.ndarrayverwenden:

real_view = np.ndarray(data.shape[:1], dtype=dt2, buffer=data)

Dies ermöglicht eine echte Ansicht der Daten:

>>> real_view
array([(['a', '1'],), (['a', 'z'],), (['b', 'a'],)], dtype=[('x', 'O', (2,))])
>>> real_view.base is data
True

Wie gezeigt funktioniert dies nur, wenn die Daten C-zusammenhängende Zeilen aufweisen.