1

I have a dtype like this:

>>> dt = np.dtype([('x', object, 3)])
>>> dt
dtype([('x', 'O', (3,))])

One field named 'x', containing three pointers. I would like to construct an array with a single element of this type:

>>> a = np.array([(['a', 'b', 'c'])], dtype=dt)
>>> b = np.array([(np.array(['a', 'b', 'c'], dtype=object))], dtype=dt)
>>> c = np.array((['a', 'b', 'c']), dtype=dt)
>>> d = np.array(['a', 'b', 'c'], dtype=dt)

>>> e = np.array([([['a', 'b', 'c']])], dtype=dt)

All five of these statements yield the same incorrect result:

array([[(['a', 'a', 'a'],), (['b', 'b', 'b'],), (['c', 'c', 'c'],)]],
      dtype=[('x', 'O', (3,))])

If I try to drop the inner list/array, I get an error:

>>> f = np.array([('a', 'b', 'c')], dtype=dt)
ValueError: could not assign tuple of length 3 to structure with 1 fields.

Same error happens for

>>> g = np.array(('a', 'b', 'c'), dtype=dt)

I've run out of possible combinations to try. The result I am looking for is

 array([(['a', 'b', 'c'],)], dtype=[('x', 'O', (3,))])

How do I create an array that has one element of the specified dtype?

So far, the only approach that I've found is manual assignment:

z = np.empty(1, dtype=dt)
z['x'][0, :] = ['a', 'b', 'c']

OR

z[0]['x'] = ['a', 'b', 'c']

This seems like an unnecessary workaround for something that np.array ought to be able to handle out of the box.

6
  • Maybe should be dt = np.dtype([('x', object, 3)])? Commented Oct 5, 2020 at 15:41
  • It looks like some of your attempts to create a tuple of length 1 are missing the required trailiing comma. Try a = np.array([(['a', 'b', 'c'],)], dtype=dt) Commented Oct 5, 2020 at 15:43
  • I also just came across same task today, the only way I found out is first to create empty/zeros array of np.object_ dtype and then to assign necessary elements to it. Commented Oct 5, 2020 at 15:54
  • @Arty. I came across this trying to answer your earlier question :) Commented Oct 5, 2020 at 16:07
  • @WarrenWeckesser. I fixed the dtype. I copied it into my console, realized my mistake, and only copied the correct output back :) Commented Oct 5, 2020 at 16:08

1 Answer 1

1
In [44]: dt = np.dtype([('x', object, 3)])   # corrected
In [45]: dt
Out[45]: dtype([('x', 'O', (3,))])
In [46]: np.empty(3, dt)
Out[46]: 
array([([None, None, None],), ([None, None, None],),
       ([None, None, None],)], dtype=[('x', 'O', (3,))])
In [47]: np.array([(['a','b','c'],)], dt)
Out[47]: array([(['a', 'b', 'c'],)], dtype=[('x', 'O', (3,))])

Input formatting should match output formatting.

In [48]: arr = np.empty(3, dt)
In [49]: arr['x']
Out[49]: 
array([[None, None, None],
       [None, None, None],
       [None, None, None]], dtype=object)
In [50]: arr['x'][0]
Out[50]: array([None, None, None], dtype=object)
In [51]: arr['x'][0] = ['a','b','c']
In [52]: arr
Out[52]: 
array([(['a', 'b', 'c'],), ([None, None, None],), ([None, None, None],)],
      dtype=[('x', 'O', (3,))])
Sign up to request clarification or add additional context in comments.

2 Comments

Got it. Missing comma. I'm almost tempted to close as a typo but the answer is good.
I think you're missing the assignment of empty(...) to arr,

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.