如何获取嵌套numpy结构化数组的字段(高级索引)



我有一个复杂的嵌套结构数组(通常用作重数组(。对于这个例子,它被简化了,但在实际情况中有多个级别。

c = [('x','f8'),('y','f8')]
A = [('data_string','|S20'),('data_val', c, 2)]
zeros = np.zeros(1, dtype=A)
print(zeros["data_val"]["x"])

我正试图索引";x〃;嵌套数组数据类型的数据类型,不包含定义前面命名字段的。我希望像print(zeros[:,"x"])这样的东西能让我对所有顶级数据进行切片,但它不起作用。

有没有方法通过访问嵌套结构数组的字段名来对其进行花式索引?

我不知道显示结果数组是否有助于可视化嵌套。

In [279]: c = [('x','f8'),('y','f8')]
...: A = [('data_string','|S20'),('data_val', c, 2)]
...: arr = np.zeros(2, dtype=A)
In [280]: arr
Out[280]: 
array([(b'', [(0., 0.), (0., 0.)]), (b'', [(0., 0.), (0., 0.)])],
dtype=[('data_string', 'S20'), ('data_val', [('x', '<f8'), ('y', '<f8')], (2,))])

注意()[]的嵌套如何反映字段的嵌套。

arr.dtype只能直接访问顶级字段名称:

In [281]: arr.dtype.names
Out[281]: ('data_string', 'data_val')
In [282]: arr['data_val']
Out[282]: 
array([[(0., 0.), (0., 0.)],
[(0., 0.), (0., 0.)]], dtype=[('x', '<f8'), ('y', '<f8')])

但访问了一个字段后,我们可以查看它的字段:

In [283]: arr['data_val'].dtype.names
Out[283]: ('x', 'y')
In [284]: arr['data_val']['x']
Out[284]: 
array([[0., 0.],
[0., 0.]])

记录编号索引是独立的,在通常意义上可以是多维的:

In [285]: arr[1]['data_val']['x'] = [1,2]
In [286]: arr[0]['data_val']['y'] = [3,4]
In [287]: arr
Out[287]: 
array([(b'', [(0., 3.), (0., 4.)]), (b'', [(1., 0.), (2., 0.)])],
dtype=[('data_string', 'S20'), ('data_val', [('x', '<f8'), ('y', '<f8')], (2,))])

由于data_val字段具有(2,(形状,我们可以将该索引与arr:的(2

In [289]: arr['data_val']['x']
Out[289]: 
array([[0., 0.],
[1., 2.]])
In [290]: arr['data_val']['x'][[0,1],[0,1]]
Out[290]: array([0., 2.])
In [291]: arr['data_val'][[0,1],[0,1]]
Out[291]: array([(0., 3.), (2., 0.)], dtype=[('x', '<f8'), ('y', '<f8')])

我提到字段索引类似于dict索引。注意字段的显示:

In [294]: arr.dtype.fields
Out[294]: 
mappingproxy({'data_string': (dtype('S20'), 0),
'data_val': (dtype(([('x', '<f8'), ('y', '<f8')], (2,))), 20)})

每个记录存储为一个52字节的块:

In [299]: arr.itemsize
Out[299]: 52
In [300]: arr.dtype.str
Out[300]: '|V52'

其中20个是data_string,32个是2个c字段

In [303]: arr['data_val'].dtype.str
Out[303]: '|V16'

您可以要求提供字段列表,然后获得一种特殊类型的view。它的dtype显示与略有不同

In [306]: arr[['data_val']]
Out[306]: 
array([([(0., 3.), (0., 4.)],), ([(1., 0.), (2., 0.)],)],
dtype={'names': ['data_val'], 'formats': [([('x', '<f8'), ('y', '<f8')], (2,))], 'offsets': [20], 'itemsize': 52})
In [311]: arr['data_val'][['y']]
Out[311]: 
array([[(3.,), (4.,)],
[(0.,), (0.,)]],
dtype={'names': ['y'], 'formats': ['<f8'], 'offsets': [8], 'itemsize': 16})

每个"data_val"在52字节的记录中开始20个字节。每个"y"在其16字节的记录中开始8个字节。

语句zeros['data_val']在数组中创建一个视图,该视图在该点上可能已经不连续。您可以提取x的多个值,因为c是一个数组类型,这意味着x具有明确定义的步长和形状。语句zeros[:, 'x']的语义非常不清楚。例如,没有xdata_string会发生什么?我预计会出现错误;你可能会期待其他的东西。

我能看到索引被简化的唯一方法是,如果您直接将c扩展到A,有点像C中的匿名结构,只是使用数组无法轻松做到这一点。

最新更新