将层次结构添加到numpy结构化数组

时间:2013-01-07 05:32:36

标签: python numpy recarray

我想使用具有多个命名字段的现有数组,并创建一个新数组(或在适当位置更改它),其中一个字段的层次结构dtype等于原始dtype。也就是说,

newarray = np.array(oldarray, dtype=[('old',oldarray.dtype)])

使newarray['old']的形状和结构与oldarray

相同

以下是一个例子:

In [1]: import numpy as np

In [2]: dt = np.dtype([('name',np.str_,2),('val',np.float_)])

In [3]: constants = np.array([('pi',3.14),('e',2.72)],dtype=dt)

In [4]: constants
Out[4]: 
array([('pi', 3.14), ('e', 2.72)], 
      dtype=[('name', '|S2'), ('val', '<f8')])

In [5]: numbers = constants.astype([('constants',dt)])

但这给了我全部零:

In [6]: numbers
Out[6]: 
array([(('', 0.0),), (('', 0.0),)], 
      dtype=[('constants', [('name', '|S2'), ('val', '<f8')])])

如果我尝试制作副本,我会遇到同样的问题:

In [7]: numbers = np.array(constants,dtype=[('constants',dt)])

In [8]: numbers
Out[8]: 
array([(('', 0.0),), (('', 0.0),)], 
      dtype=[('constants', [('name', '|S2'), ('val', '<f8')])])

另外:有人知道为什么这种情况发生了吗?

2 个答案:

答案 0 :(得分:2)

您可以使用新的dtype(http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.view.html):(/)获取原始数组的view p>

>>> import numpy as np
>>> dt = np.dtype([('name',np.str_,2),('val',np.float_)])
>>> constants = np.array([('pi',3.14),('e',2.72)],dtype=dt)
>>> 
>>> numbers = constants.view([('constants',dt)])
>>> 
>>> numbers['constants']
array([('pi', 3.14), ('e', 2.72)], 
      dtype=[('name', '|S2'), ('val', '<f8')])

请注意,生成的数组numbers是原始数组的视图,因此其中一个数据的更改也会影响另一个数组。

答案 1 :(得分:0)

我可以通过列出原始数组来解决问题:

In [9]: numbers = np.array([constants],dtype=[('constants',dt)])

In [10]: numbers
Out[10]: 
array([[(('pi', 3.14),), (('e', 2.72),)]], 
      dtype=[('constants', [('name', '|S2'), ('val', '<f8')])])

但是当我看到它时,我当然在列表中有一个额外的嵌套:

In [11]: numbers['constants']
Out[11]: 
array([[('pi', 3.14), ('e', 2.72)]], 
      dtype=[('name', '|S2'), ('val', '<f8')])

In [12]: numbers['constants']['name']
Out[12]: 
array([['pi', 'e']], 
      dtype='|S2')

我真的只想要列表中的第一项:

In [13]: numbers[0]
Out[13]: 
array([(('pi', 3.14),), (('e', 2.72),)], 
      dtype=[('constants', [('name', '|S2'), ('val', '<f8')])])

我也可以通过以后展平数组来实现这一点:

In [14]: numbers.flatten()
Out[14]: 
array([(('pi', 3.14),), (('e', 2.72),)], 
      dtype=[('constants', [('name', '|S2'), ('val', '<f8')])])

In [15]: numbers.flatten()['constants']
Out[15]: 
array([('pi', 3.14), ('e', 2.72)], 
      dtype=[('name', '|S2'), ('val', '<f8')])

In [16]: numbers.flatten()['constants']['name']
Out[16]: 
array(['pi', 'e'], 
      dtype='|S2')

但这不是一个黑客?我最终想要的是这个数组:

In [17]: numbers = np.array([(('pi', 3.14),), (('e', 2.72),)],dtype=[('constants',dt)])

In [18]: numbers['constants']
Out[18]: 
array([('pi', 3.14), ('e', 2.72)], 
      dtype=[('name', '|S2'), ('val', '<f8')])

In [19]: numbers['constants']['name']
Out[19]: 
array(['pi', 'e'], 
      dtype='|S2')

无需制作单项列表然后将其展平。有更好的想法吗?