3

I wanted to access my array both as a 3-element entity (3d position) and individual element (each of x,y,z coordinate). After some researching, I ended up doing the following.

>>> 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.]])

However, I've always been making array in this style:

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

But I can't find a way to specify both the offset and the shape of the element at the same time in this style. Is there a way to do this?

1 Answer 1

2

In reference to the docs page, https://docs.scipy.org/doc/numpy-1.14.0/reference/arrays.dtypes.html

you are using the fields dictionary form, with (data-type, offset) value

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

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

The display for the resulting dtype is the other dictionary format:

{'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 aren't mentioned any where else on the documentation page.

The last format is a union type. It's a little unclear as to whether that's allowed or discouraged. The examples don't seem to work. There have been some changes in how multifield indexing works, and that may have affected this.

Let's play around with various ways of viewing the array:

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]])
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the interesting tests. It's weird that the example does not work for you. It works for me in Python 3.5 and 3.6. Anyways, I would appreciate if you can confirm there is no other way to achieve this than the example. Maybe I have to live with that style of dtype.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.