jphollowed jphollowed - 1 year ago 89
Python Question

Filling NumPy array with object instances?

I am trying to add object instances of

to a
array , and am getting an error:

ValueError: setting an array element with a sequence.

objects look something like this:

<Angle 1.2557346257567 deg>

If I put them in a normal Python list, then I get:

s = [<Angle 1.2562500714928306 deg>,
<Angle 1.2562500714928306 deg>,
<Angle 1.2562500714928306 deg>]
>>> 3
>>> TypeError: 'Angle' object with a scalar value has no len()

So, my first question is, in what way is a Python object a sequence? And, since numpy arrays need to be initialized to specific dimensions, how do I find the "length" of this object so that I can load them into a numpy array?

Answer Source

I don't have astrop package and don't know the details of the Angle object. But I can make some Python and numpy observations.

<Angle 1.2557346257567 deg> is the string representation of this object, produced by its __repr__ method.

The TypeError for len(s[0]) means that this object does not a __len__ method. It is not a subclass of list, nor a specialized numpy array. Check its docs. It may have a way of yielding a numeric value or values.

You don't say how you are trying to 'add' an Angle to an array, or what kind of array. If the array is numeric, e.g. dtype=float, then doing

A[0]= <Angle...> 

is not going to work, because Angle is not a number, nor does it produce one - at least not without some method. You need to tell us what this target array is supposed to contain. Numbers, angle objects?

You can build an array that contains objects. np.array(s) might work. It does when the list contains dictionary objects.

In [67]: ll
Out[67]: [{1: 2}, {}, {'a': 1, 'b': 2}]

In [68]: np.array(ll)
Out[68]: array([{1: 2}, {}, {'b': 2, 'a': 1}], dtype=object)

But np.array([...]) can be tricky to use, since it's designed to produce a multidimensional array of numbers - if possible.

Or you might have to make A = np.zeros((3,),dtype=object) array, and assign values individually, A[0]=s[0]. But such an object array is just a variant on a list. It's not a 2d array of numbers.

From a previous astropy question:

How to covert np.ndarray into astropy.coordinates.Angle class?

Angle(angles_quantity).wrap_at('360d').value # This returns a simple ndarray again.


Digging into the docs and astropy github code, I see that Angle is a subclass of Quantity which is a subclass of ndarray. It tries, in effect to be an array (or scalar) with appropriate unit definition.

The .value method returns self.view(np.ndarray), unless it's shape is 0d, in which case it returns self.item(), the scalar value.

So you should be able to define an Angle with multiple values, e.g.

Angle([1.23, 1.24, 1.25])

I don't know if you can join multiple Angles into one


where s is your list of Angle objects, might work. I don't see Angle versions of concatenate or stack.