将numpy记录数组放在另一个记录数组python

时间:2015-10-29 20:49:16

标签: python arrays numpy

我有以下记录数组。但是每个元素都需要它自己的记录数组来描述有关该元素的信息。现在这不是代码我只是以可读的方式显示信息。例如:

我有一组寄存器,其中包含宽度和偏移等属性。

登记册清单

Registers     offsets    width

Register_1    1          5
Register_2    2          10
Register_3    3          15
Register_4    4          20

每个寄存器还有一组字段,这些字段具有特定值,如位和长度

在register_1内部,我们有以下字段

register_1
{
#field names      bit     length
field_1           1       10
field_2           2       20
field_3           3       30

}

实际python代码

dtype={
    'names' : ('name','offset','width'),
    'formats' : ('U20','U20','U20')}

registers= np.zeros(10,dtype)

registers[0]=('register_1','1','5')
registers[1]=('register_2','2','10')
registers[2]=('register_3','3','15')
registers[3]=('register_4','4','20')

现在我想将每个寄存器与它们的字段相关联,首先想到的是在寄存器记录数组中嵌套另一个记录数组。

伪python代码

type={
    'names' : ('name','bit','length'),
    'formats' : ('U20','U20','U20')}

fields= np.zeros(10,type)

 dtype={
    'names' : ('name','offset','width',fields),
    'formats' : ('U20','U20','U20','U20')}

regsiters= np.zeros(10,dtype)

有什么建议吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

type(错误名称!)转换为dtype

In [277]: dt1=np.dtype(type)
In [278]: dt1
Out[278]: dtype([('name', '<U20'), ('bit', '<U20'), ('length', '<U20')])

构建一个复合dtype。请注意,“字段”的格式为(dt1,3) - 即由3个dt1类型元素组成的子数组。

In [279]: dt2=np.dtype({
    'names' : ('name','offset','width','fields'),
    'formats' : ('U20','U20','U20',(dt1,3))})
In [280]: registers=np.zeros(4,dtype=dt2)
In [281]: registers
Out[281]: 
array([('', '', '', [('', '', ''), ('', '', ''), ('', '', '')]),
       ('', '', '', [('', '', ''), ('', '', ''), ('', '', '')]),
       ('', '', '', [('', '', ''), ('', '', ''), ('', '', '')]),
       ('', '', '', [('', '', ''), ('', '', ''), ('', '', '')])], 
      dtype=[('name', '<U20'), ('offset', '<U20'), ('width', '<U20'), ('fields', [('name', '<U20'), ('bit', '<U20'), ('length', '<U20')], (3,))])

填写姓名:

In [283]: registers['name']='register_1 register_2 register_3 register_4'.split()

和其他两个领域:

In [284]: registers['offset']=[1,2,3,4]
In [285]: registers['width']=[5,10,15,20]
In [286]: registers
Out[286]: 
array([('register_1', '1', '5', [('', '', ''), ('', '', ''), ('', '', '')]),
       ('register_2', '2', '10', [('', '', ''), ('', '', ''), ('', '', '')]),
       ('register_3', '3', '15', [('', '', ''), ('', '', ''), ('', '', '')]),
       ('register_4', '4', '20', [('', '', ''), ('', '', ''), ('', '', '')])], 
      dtype=[('name', '<U20'), ('offset', '<U20'), ('width', '<U20'), ('fields', [('name', '<U20'), ('bit', '<U20'), ('length', '<U20')], (3,))])

fields元素的registers[0]值可以用相同的方式填写:

In [288]: registers[0]['fields']
Out[288]: 
array([('', '', ''), ('', '', ''), ('', '', '')], 
      dtype=[('name', '<U20'), ('bit', '<U20'), ('length', '<U20')])

现在registers有4个字段,您无法使用以下字段填写其中的3个字段:

In [289]: registers[0]=('register_1','1','5')
...
ValueError: size of tuple must match number of fields.

元组包含了“字段”字段所需的所有值(为什么选择这样令人困惑的名字?)。

使用dtype dt1创建一个数组,然后填充它。

In [290]: regfield=np.zeros(3,dtype=dt1)
In [291]: regfield
Out[291]: 
array([('', '', ''), ('', '', ''), ('', '', '')], 
      dtype=[('name', '<U20'), ('bit', '<U20'), ('length', '<U20')])
In [292]: regfield[0]=('field1',1,10)
In [293]: regfield[1]=('field2',2,20)
In [294]: regfield[2]=('field3',3,30)

现在,您可以将其作为registers元组中的值包含在内。

In [295]: registers[0]=('register_1','1','5',regfield)
In [296]: registers[0]
Out[296]: ('register_1', '1', '5', [('field1', '1', '10'), ('field2', '2', '20'), ('field3', '3', '30')])

我可以将字段名复制到其他寄存器:

In [300]: fieldnames=registers['fields']['name'][0]
In [301]: registers['fields']['name']
Out[301]: 
array([['field1', 'field2', 'field3'],
       ['', '', ''],
       ['', '', ''],
       ['', '', '']], 
      dtype='<U20')
In [302]: registers['fields']['name']=fieldnames
In [303]: registers['fields']['name']
Out[303]: 
array([['field1', 'field2', 'field3'],
       ['field1', 'field2', 'field3'],
       ['field1', 'field2', 'field3'],
       ['field1', 'field2', 'field3']], 
      dtype='<U20')
In [304]: registers['fields']
Out[304]: 
array([[('field1', '1', '10'), ('field2', '2', '20'), ('field3', '3', '30')],
       [('field1', '', ''), ('field2', '', ''), ('field3', '', '')],
       [('field1', '', ''), ('field2', '', ''), ('field3', '', '')],
       [('field1', '', ''), ('field2', '', ''), ('field3', '', '')]], 
      dtype=[('name', '<U20'), ('bit', '<U20'), ('length', '<U20')])

新dtype:

In [333]: dt3=np.dtype({
    'names' : ('name','offset','width','fields'),
    'formats' : ('U20','U20','U20', 'O')})
In [334]: registers=np.zeros(4,dtype=dt3)
In [335]: registers
Out[335]: 
array([('', '', '', 0), ('', '', '', 0), ('', '', '', 0), ('', '', '', 0)], 
      dtype=[('name', '<U20'), ('offset', '<U20'), ('width', '<U20'), ('fields', 'O')])

将值分配给registers[0]regfield我之前定义的3元素数组。

In [337]: registers[0]=('register_1', '1', '5', regfield)
In [338]: registers
Out[338]: 
array([ ('register_1', '1', '5', [('field1', '1', '10'), ('field2', '2', '20'), ('field3', '3', '30')]),
       ('', '', '', 0), 
       ('', '', '', 0), 
       ('', '', '', 0)], 
      dtype=[('name', '<U20'), ('offset', '<U20'), ('width', '<U20'), ('fields', 'O')])
...

显示与我们之前的显示类似,但现在每个寄存器可以有不同数量的fields

我们可以通过查看其ID来验证fields' field of寄存器[0] is the regfield`数组中的对象。

In [343]: id(regfield)
Out[343]: 166843840
In [344]: id(registers[0]['fields'])
Out[344]: 166843840