使用另一种样式的shape和offset参数创建一个numpy数组

时间:2018-03-27 02:40:28

标签: python arrays numpy

我想要将我的数组作为3元素实体(3d位置)和单个元素(x,y,z坐标中的每一个)访问。 经过一番研究,我最终做了以下事情。

>>> import numpy as np
>>> arr = np.zeros(5, dtype={'pos': (('<f8', (3,)), 0),
                               'x': (('<f8', 1), 0),
                               'y': (('<f8', 1), 8),
                               'z': (('<f8', 1), 16)})
>>> arr["x"] = 0
>>> arr["y"] = 1
>>> arr["z"] = 2

# I can access the whole array by "pos"
>>> print(arr["pos"])
>>> array([[ 1.,  2.,  3.],
           [ 1.,  2.,  3.],
           [ 1.,  2.,  3.],
           [ 1.,  2.,  3.],
           [ 1.,  2.,  3.]])

然而,我一直在以这种方式制作阵列:

>>> arr = np.zeros(10, dtype=[("pos", "f8", (3,))])

但我找不到在这种风格中同时指定元素的偏移量和形状的方法。有没有办法做到这一点?

1 个答案:

答案 0 :(得分:2)

参考文档页面https://docs.scipy.org/doc/numpy-1.14.0/reference/arrays.dtypes.html

您正在使用字段字典表单,(data-type, offset)

{'field1': ..., 'field2': ..., ...}

dt1 = {'pos': (('<f8', (3,)), 0),
       'x': (('<f8', 1), 0),
       'y': (('<f8', 1), 8),
       'z': (('<f8', 1), 16)}

结果dtype的显示是另一种字典格式:

{'names': ..., 'formats': ..., 'offsets': ..., 'titles': ..., 'itemsize': ...}

In [15]: np.dtype(dt1)
Out[15]: dtype({'names':['x','pos','y','z'], 
                'formats':['<f8',('<f8', (3,)),'<f8','<f8'], 
                'offsets':[0,0,8,16], 'itemsize':24})

In [16]: np.dtype(dt1).fields
Out[16]: 
mappingproxy({'pos': (dtype(('<f8', (3,))), 0),
              'x': (dtype('float64'), 0),
              'y': (dtype('float64'), 8),
              'z': (dtype('float64'), 16)})

offsets未在文档页面的任何其他位置提及。

最后一种格式是union类型。关于这是允许还是气馁,有点不清楚。这些例子似乎不起作用。多字段索引的工作原理发生了一些变化,这可能会对此产生影响。

让我们以各种方式查看阵列:

In [25]: arr
Out[25]: 
array([(0., [ 0. , 10. ,  0. ], 10., 0. ),
       (1., [ 1. , 11. ,  0.1], 11., 0.1),
       (2., [ 2. , 12. ,  0.2], 12., 0.2),
       (3., [ 3. , 13. ,  0.3], 13., 0.3),
       (4., [ 4. , 14. ,  0.4], 14., 0.4)],
      dtype={'names':['x','pos','y','z'], 'formats':['<f8',('<f8', (3,)),'<f8','<f8'], 'offsets':[0,0,8,16], 'itemsize':24})

In [29]: dt3=[('x','<f8'),('y','<f8'),('z','<f8')]
In [30]: np.dtype(dt3)
Out[30]: dtype([('x', '<f8'), ('y', '<f8'), ('z', '<f8')])
In [31]: np.dtype(dt3).fields
Out[31]: 
mappingproxy({'x': (dtype('float64'), 0),
              'y': (dtype('float64'), 8),
              'z': (dtype('float64'), 16)})
In [32]: arr.view(dt3)
Out[32]: 
array([(0., 10., 0. ), (1., 11., 0.1), (2., 12., 0.2), (3., 13., 0.3),
       (4., 14., 0.4)], dtype=[('x', '<f8'), ('y', '<f8'), ('z', '<f8')])

In [33]: arr['pos']
Out[33]: 
array([[ 0. , 10. ,  0. ],
       [ 1. , 11. ,  0.1],
       [ 2. , 12. ,  0.2],
       [ 3. , 13. ,  0.3],
       [ 4. , 14. ,  0.4]])

In [35]: arr.view('f8').reshape(5,3)
Out[35]: 
array([[ 0. , 10. ,  0. ],
       [ 1. , 11. ,  0.1],
       [ 2. , 12. ,  0.2],
       [ 3. , 13. ,  0.3],
       [ 4. , 14. ,  0.4]])

In [37]: arr.view(dt4)
Out[37]: 
array([([ 0. , 10. ,  0. ],), ([ 1. , 11. ,  0.1],),
       ([ 2. , 12. ,  0.2],), ([ 3. , 13. ,  0.3],),
       ([ 4. , 14. ,  0.4],)], dtype=[('pos', '<f8', (3,))])
In [38]: arr.view(dt4)['pos']
Out[38]: 
array([[ 0. , 10. ,  0. ],
       [ 1. , 11. ,  0.1],
       [ 2. , 12. ,  0.2],
       [ 3. , 13. ,  0.3],
       [ 4. , 14. ,  0.4]])