Array math on numpy structured arrays

Viewed 138
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,:]
1 Answers

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')])
Related