2

I need an efficient heterogeneous array in which the first element is an int and the rest are floats. After creating it, however, basic array operations are exploding.

A = np.zeros(1, dtype='i4, f4, f4')
B = np.array([3,3,3])
A + B
TypeError: invalid type promotion
3
  • Why don't you also provide the dtype for B? Commented May 3, 2016 at 15:31
  • The dtype syntax is creating one - three tuple rather than one - three element array. Look at custom dtypes for np.zeros. Commented May 3, 2016 at 16:55
  • @bejota that's not what I meant. I meant instead of letting it choose the default int type to use, specify it, or specify record types. If you try to give the dtype 'i4, f4, f4' for B, the error you get explains why the OP's original request doesn't make sense (you need bytes to interpret an array like that). So use a record type and iterate over the fields. Commented May 3, 2016 at 22:37

1 Answer 1

4

With a structured array like this, operations that call for iteration over the fields generally don't work.

Even adding A to itself does not work:

In [476]: A = np.zeros(1, dtype='i4, f4, f4')

In [477]: A+A
...
TypeError: ufunc 'add' did not contain a loop with signature matching types dtype([('f0', '<i4'), ('f1', '<f4'), ('f2', '<f4')]) ....

In other words, there's a way of adding an int to an int, a float to an int, but not a way of adding a A element to another element.

An element of A is a tuple or a numpy.void (depending on how you access it)

In [478]: A.item()
Out[478]: (0, 0.0, 0.0)

In [479]: type(A.item())
Out[479]: tuple

In [480]: type(A[0])
Out[480]: numpy.void

To work across the fields of a structured array you usually have to iterate over the field names.

In [493]: B=np.arange(3)

In [494]: for i,name in enumerate(A.dtype.names):
   A[name] = A[name]+B[i]
   .....: 

In [495]: A
Out[495]: 
array([(0, 1.0, 2.0)], 
      dtype=[('f0', '<i4'), ('f1', '<f4'), ('f2', '<f4')])

If all the fields have the same type, e.g. dtype='i4, i4, i4', then it is possible to view the structured array as a homogeneous dtype, and perform regular math on it. But with your mix of floats and ints, that isn't possible.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.