6

我是使用 numpy 数组的新手,但在创建结构化数组时遇到了麻烦。我想创建类似于 Matlab 结构的东西,其中字段可以是不同形状的数组。

a=numpy.array([1, 2, 3, 4, 5, 6,]);
b=numpy.array([7,8,9]);
c=numpy.array([10,11,12,13,14,15,16,17,18,19,20]);

##Doesn't do what I want
data=numpy.array([a, b, c],dtype=[('a','f8'),('b','f8'),('c','f8')]);  

我想data['a']返回矩阵a,data['b']返回矩阵b等。在Matlab结构中读取时,数据以这种格式保存,所以我知道它必须是可能的。

4

2 回答 2

14

恐怕不经常扭动 NumPy 的手臂是不可能的。

看,NumPy 背后的想法是提供同构数组,即所有具有相同类型的元素数组。这种类型可以是简单的 ( int, float...) 或更复杂的 ( [('',int),('',float),('',"|S10")]),但无论如何,所有元素都具有相同的类型。这允许一些非常有效的内存布局。

因此,结构化数组本质上要求字段(各个子块)无论位置如何都具有相同的大小。检查以下内容:

>>> np.zeros(3,dtype=[('a',(int,3)),('b',(float,5))])

它定义了一个包含三个元素的数组;每个元素由两个子块组成,a并且ba是三块一排intsb五块一排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数组。

于 2012-09-11T20:59:52.047 回答
7

在 python 中,字典大致类似于 Matlab 中的结构。您可以尝试以下方法,看看它是否适合您:

>>> data = {'a':a, 'b':b, 'c':c}
>>> data['a'] is a
True
于 2012-09-11T21:04:42.133 回答