恐怕不经常扭动 NumPy 的手臂是不可能的。
看,NumPy 背后的想法是提供同构数组,即所有具有相同类型的元素数组。这种类型可以是简单的 ( int
, float
...) 或更复杂的 ( [('',int),('',float),('',"|S10")])
,但无论如何,所有元素都具有相同的类型。这允许一些非常有效的内存布局。
因此,结构化数组本质上要求字段(各个子块)无论位置如何都具有相同的大小。检查以下内容:
>>> np.zeros(3,dtype=[('a',(int,3)),('b',(float,5))])
它定义了一个包含三个元素的数组;每个元素由两个子块组成,a
并且b
;a
是三块一排ints
,b
五块一排floats
。但是一旦你在 中定义了块的初始大小dtype
,你就会被困住(好吧,你总是可以切换,但那是另一回事了)。
有一个解决方法:使用dtype=object
. 这样,您将构建一个异构项目数组,例如一个不同大小的列表数组。但是这样会失去很多 NumPy 的能力。还是举个例子:
>>> x=np.zeros(3, dtype=[('a',object), ('b',object)])
>>> x['a'][0] = [1,2,3,4]
>>> x['b'][-1] = "ABCDEF"
>>> print x
[([1, 2, 3, 4], 0) (0, 0) (0, 'ABCD')]
所以,我们只是构造了一个...对象的数组。我在某处放了一个列表,在其他地方放了一个字符串,它可以工作。您可以按照相同的示例构建您想要的数组:
blob = np.array([(a,b,c)],dtype=[('a',object),('b',object),('c',object)])
但是,您真的应该三思而后行,这是否真的意味着您的目的,另一种结构可能会更有效。
旁注:请注意[(a,b,c)]
上面表达式的部分:注意()
?您基本上是在告诉 NumPy 构造一个包含 1 个元素的数组,该数组由三个子元素(a,b,c
每个子元素一个)组成,每个子元素都是一个对象。如果你不放()
,NumPy 会抱怨很多。
最后一条评论:如果你访问你的字段blob['a']
,你会得到一个大小的数组,(1,)
并且dtype=object
: 只是blob['a'].item()
用来取回你的原始(6,)
int
数组。