Getting Attributes From Arrays Of Objects In Numpy
Solution 1:
The closest thing to what you want is to use a recarray
instead of an ndarray
of Python objects:
num_stars = 10
dtype = numpy.dtype([('x', float), ('y', float), ('colour', float)])
a = numpy.recarray(num_stars, dtype=dtype)
a.colour = numpy.arange(num_stars)
print a.colour
prints
[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
Using a NumPy array of Python objects usually is less efficient than using a plain list
, while a recarray
stores the data in a more efficient format.
Solution 2:
You could use numpy.fromiter(s.color for s in stars)
(note lack of square brackets). That will avoid creating the intermediate list, which I imagine you might care about if you are using numpy.
(Thanks to @SvenMarnach and @DSM for their corrections below).
Solution 3:
In case star
is a more complicated class
, here is an approach to get and set
the attributes with a helper class
on top.
import numpy as np
classstar:
def__init__(self, mass=1, radius=1):
self.mass = mass
self.radius = radius
classStars(list):
__getattr__ = lambda self, attr: np.array([getattr(s, attr) for s in self])
def__setattr__(self, attr, vals):
ifhasattr(vals, '__len__'):
[s.__setattr__(attr, val) for (s,val) inzip(self,vals)]
else:
[s.__setattr__(attr, vals) for s in self]
s1 = star(1, 1.1)
s2 = star(2, 3)
S = Stars([s1, s2])
print(S.mass)
print(S.radius)
S.density = S.mass / S.radius**3print(S.density)
print(s1.density)
Of course, if the class can be reimplemented into a recarray
, it should be more efficient. Yet, such a reimplementaion might be undesirable.
Note, outer computations, like the density calculation, are still vectorised. And often those could be bottleneck, rather than setting and getting attributes.
Post a Comment for "Getting Attributes From Arrays Of Objects In Numpy"