如何在numpy中将ndarray的dtype更改为自定义类型?
我创建了一种数据类型(dtype),它是:
mytype = np.dtype([('a',np.uint8), ('b',np.uint8), ('c',np.uint8)])
所以使用这种数据类型的数组是:
test1 = np.zeros(3, dtype=mytype)
test1 是:
array([(0, 0, 0), (0, 0, 0), (0, 0, 0)],
dtype=[('a', '|u1'), ('b', '|u1'), ('c', '|u1')])
现在我有了 test2:
test2 = np.array([[1,2,3], [4,5,6], [7,8,9]])
当我使用 test2.astype(mytype)
时,结果并不是我想要的:
array([[(1, 1, 1), (2, 2, 2), (3, 3, 3)],
[(4, 4, 4), (5, 5, 5), (6, 6, 6)],
[(7, 7, 7), (8, 8, 8), (9, 9, 9)]],
dtype=[('a', '|u1'), ('b', '|u1'), ('c', '|u1')])
我希望结果是:
array([(1, 2, 3), (4, 5, 6), (7, 8, 9)],
dtype=[('a', '|u1'), ('b', '|u1'), ('c', '|u1')])
有没有什么办法可以做到?谢谢。
3 个回答
0
在创建数组的时候,如果你输入的是元组(元组是不可改变的)而不是列表(列表是可以改变的),那么只要每个元组里的元素数量和你想要的结构中的字段数量一致,程序就会自动按照你想要的方式来处理这些输入。
In[7]: test2 = np.array([(1,2,3), (4,5,6), (7,8,9)], dtype = mytype)
In[8]: test2
Out[8]:
array([(1, 2, 3), (4, 5, 6), (7, 8, 9)],
dtype=[('a', 'u1'), ('b', 'u1'), ('c', 'u1')])
为了这个目的,你不需要去使用 np.rec
等其他复杂的东西。不过,如果你输入的是列表而不是元组,那么numpy就不会像你期待的那样一一对应字段,而是会复制数据。
0
因为所有的字段都是相同类型的,所以你也可以这样做:
>>> test2.astype(np.uint8).view(mytype).squeeze(axis=-1)
array([(1, 2, 3), (4, 5, 6), (7, 8, 9)],
dtype=[('a', 'u1'), ('b', 'u1'), ('c', 'u1')])
这里需要用到“挤压”这个操作,因为 test2
是二维的,但你想要的是一维的结果。
5
你可以使用numpy.core.records里的fromarrays
方法(具体可以查看文档):
np.rec.fromarrays(test2.T, mytype)
Out[13]:
rec.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)],
dtype=[('a', '|u1'), ('b', '|u1'), ('c', '|u1')])
在使用之前,数组需要先进行转置,因为这个函数会把数组的行当作输出中结构化数组的列。你也可以看看这个问题:将二维numpy数组转换为结构化数组