问题描述
我想查看一个具有封装整个行的dtype的对象数组:
data = np.array([['a','1'],['a','z'],['b','a']],dtype=object)
dt = np.dtype([('x',object),('y',object)])
data.view(dt)
TypeError: Cannot change data-type for object array.
我尝试了以下解决方法:
dt2 = np.dtype([('x',np.object,2)])
data.view()
data.view(np.uint8).view(dt)
data.view(np.void).view(dt)
所有情况均导致相同的错误。有什么方法可以查看具有不同dtype的对象数组?
我还尝试了一种更通用的方法(此方法仅供参考,因为其功能与上面显示的相同):
dt = np.dtype(','.join(data.dtype.char * data.shape[1]))
dt2 = np.dtype([('x',data.dtype,data.shape[1])])
解决方法
似乎您总是可以使用np.array
强制查看缓冲区的视图:
view = np.array(data,dtype=dt,copy=not data.flags['C_CONTIGUOUS'])
虽然这是一种快速而肮脏的方法,但是在这种情况下,数据将被复制,并且dt2
不能正确应用:
>>> print(view.base)
None
>>> np.array(data,dtype=dt2,copy=not data.flags['C_CONTIGUOUS'])
array([[(['a','a'],),(['1','1'],)],[(['a',(['z','z'],[(['b','b'],(['a',)]],dtype=[('x','O',(2,))])
对于更正确的方法(在某些情况下),可以使用原始的np.ndarray
构造函数:
real_view = np.ndarray(data.shape[:1],buffer=data)
这可以真实显示数据:
>>> real_view
array([(['a',(['b',))])
>>> real_view.base is data
True
如图所示,这仅在数据具有C连续行时有效。