I.P. Freeley
I.P. Freeley

Reputation: 965

Array math on numpy structured arrays

import numpy as np
arr = np.array([(1,2), (3,4)], dtype=[('c1', float), ('c2', float)])
arr += 3

results in an invalid type promotion error. Is there a way I can have nice labeled columns like a structured array, but still be able to do operations like it's a simple dtype=float array?

Alternatively, is there an easy way to cast a dtype=float array into a structured array? i.e.

arr = np.array([(1,2), (3,4)], dtype=float)
arr_struc = arr.astype([('c1', float), ('c2', float)])

only where it doesn't broadcast and matches columns to names. Seems like I shouldn't have to do this loop:

arr_struc = np.zeros(2, dtype=[('c1', float), ('c2', float)])
for i,key in enumerate(arr_struc.dtype.names):  arr_struc[key] = arr[i,:]

Upvotes: 2

Views: 245

Answers (1)

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 95937

Hmmm. One option, use a view for this:

>>> import numpy as np
>>> arr = np.array([(1,2), (3,4)], dtype=[('c1', float), ('c2', float)])
>>> view = arr.view(float)
>>> view += 3
>>> arr
array([(4., 5.), (6., 7.)], dtype=[('c1', '<f8'), ('c2', '<f8')])
>>> view
array([4., 5., 6., 7.])

Not the cleanest. But it's a solution.

EDIT:

Yes, don't use astype use a view again:

>>> arr = np.array([(1,2), (3,4)], dtype=float)
>>> arr
array([[1., 2.],
       [3., 4.]])
>>> struct = arr.view(dtype=[('c1', float), ('c2', float)])
>>> struct
array([[(1., 2.)],
       [(3., 4.)]], dtype=[('c1', '<f8'), ('c2', '<f8')])
>>> struct.shape
(2, 1)

You may have to reshape it to your liking:

>>> struct.squeeze()
array([(1., 2.), (3., 4.)], dtype=[('c1', '<f8'), ('c2', '<f8')])

Upvotes: 2

Related Questions