Pedro Valverde Pedro Valverde - 2 months ago 8
Python Question

Copy a flat numpy array to an given attribute of an np.array of objects

Can I copy a 1D numpy array to an given attribute of an np.array of objects without using a for loop?
For filling the "percentage" property of all PlotInputGridData objects in objarray with the "dist" array, i use something like this:

import numpy as np

class PlotInputGridData(object):
def __init__(self):
self.rangemin = 0
self.rangemax = 0
self.rangelabel = ''
self.percentage = 0
self.number = 0

objarray = np.arange(6, dtype=PlotInputGridData)
for i in range(objarray.size):
t = PlotInputGridData()
objarray[i] = t

dist = np.array([52, 26, 12, 6, 3, 1], dtype=np.int)

for i in range(dist.size):
objarray[i].percentage = dist[i]


i need to do


  • objarray[0].percentage= dist[0]

  • objarray[1].percentage= dist[1]

  • ... and so on



is there any way of copying dist[] to objarray[].percentage in a more concise way without the for loop on the last 2 lines?

Answer

I don't think there is a way to do that assignment without a for-loop.

You could do it if you used a structured array instead of an array of objects. The class PlotInputGridData is just a few fields, so the data it holds is easily represented as a structured data type instead of a Python class.

For example,

In [15]: grid_data_type = np.dtype([('rangemin', float),
    ...:                            ('rangemax', float),
    ...:                            ('rangelabel', 'S16'),
    ...:                            ('percentage', float),
    ...:                            ('number', int)])

grid_data_type is a structured data type with five fields. (Change the types of the individuals fields as needed.) This data type can be used as the dtype of a numpy array:

In [16]: a = np.zeros(6, dtype=grid_data_dtype)

In [17]: dist = np.array([52, 26, 12, 6, 3, 1])

The following assigns the array dist to the 'percentage' field:

In [18]: a['percentage'] = dist

Take a look at a:

In [19]: a
Out[19]: 
array([(0.0, 0.0, b'', 52.0, 0), (0.0, 0.0, b'', 26.0, 0),
       (0.0, 0.0, b'', 12.0, 0), (0.0, 0.0, b'', 6.0, 0),
       (0.0, 0.0, b'', 3.0, 0), (0.0, 0.0, b'', 1.0, 0)], 
      dtype=[('rangemin', '<f8'), ('rangemax', '<f8'), ('rangelabel', 'S16'), ('percentage', '<f8'), ('number', '<i8')])

In [20]: a[0]
Out[20]: (0.0, 0.0, b'', 52.0, 0)

In [21]: a['percentage']
Out[21]: array([ 52.,  26.,  12.,   6.,   3.,   1.])