4

Let's say I have the following array:

arr = np.array([[1,2], [3,4]], dtype='u1')

and I want to convert it into a structured array like this one:

strarr = np.array([(1,2), (3,4)], dtype=[('a', 'u1'), ('b', 'u1')])

If I just try

arr.astype([('a', 'u1'), ('b', 'u1')])

it returns

>>> array([[(1, 1), (2, 2)],
       [(3, 3), (4, 4)]], dtype=[('a', 'u1'), ('b', 'u1')])

How can I convert the array so that it uses all elements of a row to fill the fields (provided that the numbers match) instead of duplicating each element?

2 Answers 2

6

There are special helper functions for this:

>>> from numpy.lib.recfunctions import unstructured_to_structured

So,

>>> import numpy as np
>>> arr = np.array([[1,2], [3,4]], dtype='u1')
>>> unstructured_to_structured(arr, dtype=np.dtype([('a', 'u1'), ('b', 'u1')]))
array([(1, 2), (3, 4)], dtype=[('a', 'u1'), ('b', 'u1')])

You can also create a view:

>>> arr.ravel().view(dtype=np.dtype([('a', 'u1'), ('b', 'u1')]))
array([(1, 2), (3, 4)], dtype=[('a', 'u1'), ('b', 'u1')])

And in this simple case, that is fine, but if you choose to use a view you sometimes have to worry about how the array is packed. Note, a view doesn't copy the underlying buffer! Which can make it much more efficient if you are working with large arrays.

Sign up to request clarification or add additional context in comments.

Comments

3

The data for a structured array is supposed to be a list of tuples:

In [5]: arr = np.array([[1,2], [3,4]], dtype='u1')
In [6]: alist = [tuple(i) for i in arr]
In [7]: alist
Out[7]: [(1, 2), (3, 4)]
In [9]: np.array(alist, dtype=[('a', 'u1'), ('b', 'u1')])
Out[9]: array([(1, 2), (3, 4)], dtype=[('a', 'u1'), ('b', 'u1')])

Note that the input mirrors the output display.

In this case, a view is also possible (there's no change in underlying data):

In [10]: arr.view(dtype=[('a', 'u1'), ('b', 'u1')])
Out[10]: 
array([[(1, 2)],
       [(3, 4)]], dtype=[('a', 'u1'), ('b', 'u1')])
In [11]: _.ravel()      # but needs a shape correction
Out[11]: array([(1, 2), (3, 4)], dtype=[('a', 'u1'), ('b', 'u1')])

Comments

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.