4

Suppose I have a flat list L like this:

In [97]: L
Out[97]: [2010.5, 1, 2, 3, 4, 5]

...and I want to get a structured array like this:

array((2010.5, [1, 2, 3, 4, 5]),
      dtype=[('A', '<f4'), ('B', '<u4', (5,))])

How can I most efficiently make this conversion? I can not pass the latter dtype directly to array(L, ...) or to array(tuple(L)):

In [98]: dtp                                                                                                                                                                                 [9/1451]
Out[98]: [('A', '<f4', 1), ('B', '<u4', 5)]

In [99]: array(L, dtp)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-99-32809e0456a7> in <module>()
----> 1 array(L, dtp)

TypeError: expected an object with a buffer interface
In [101]: array(tuple(L), dtp)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-101-4d0c49a9f01d> in <module>()
----> 1 array(tuple(L), dtp)

ValueError: size of tuple must match number of fields.

What does work is to pass a temporary dtype where each field has one entry, then view this with the dtype I actually want:

In [102]: tdtp
Out[102]: 
[('a', numpy.float32),
 ('b', numpy.uint32),
 ('c', numpy.uint32),
 ('d', numpy.uint32),
 ('e', numpy.uint32),
 ('f', numpy.uint32)]

In [103]: array(tuple(L), tdtp).view(dtp)
Out[103]: 
array((2010.5, [1, 2, 3, 4, 5]), 
      dtype=[('A', '<f4'), ('B', '<u4', (5,))])

But to create this temporary dtype is an additional step that I would like to avoid if possible.

Is it possible to go directly from my flat list to my structured dtype, without using the intermediate dtype shown above?

(Note: in my real use case I have a reading routine reading a custom file format and many values per entry; so I would prefer to avoid a situation where I need to construct both the temporary and the actual dtype by hand.)

1 Answer 1

4

Instead of passing tuple(L) to array, pass an argument with nested values that match the nesting of the dtype. For the example you showed, you could pass in (L[0], L[1:]):

In [28]: L
Out[28]: [2010.5, 1, 2, 3, 4, 5]

In [29]: dtp
Out[29]: [('A', '<f4', 1), ('B', '<u4', 5)]

In [30]: array((L[0], L[1:]), dtype=dtp)
Out[30]: 
array((2010.5, [1L, 2L, 3L, 4L, 5L]), 
      dtype=[('A', '<f4'), ('B', '<u4', (5,))])
Sign up to request clarification or add additional context in comments.

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.