I would like to get the attribute of every object contained in an ndarray. Consider the following code, where after vectorization the function returns an ndarray with the objects. From each of these objects in the array, I would like to get the attribute and store the attributes in a new array.
The classes and functions are a dummy for more complex classes and functions. I am aware of the fact that from stud = new_student(["Michael","Rachel"], [1,2]); stud.name
I could get a list with the names, however this is not possible with the function I am using instead of new_student
.
import numpy as np class Student: # class variable stream = "COE" # Constructor def __init__(self, name, roll_no): self.name = name self.roll_no = roll_no def new_student(name, roll_no): return Student(name, roll_no) new_student_vec = np.vectorize(new_student) studArr = new_student_vec(["Michael","Rachel"], [1,2]) studArr.name
Advertisement
Answer
In [3]: class Student: ...: ...: # class variable ...: stream = "COE" ...: ...: # Constructor ...: def __init__(self, name, roll_no): ...: ...: self.name = name ...: self.roll_no = roll_no ...: def __repr__(self): ...: return f'Student <{self.name}, {self.roll_no}>' ...: ...: ...: def new_student(name, roll_no): ...: return Student(name, roll_no) ...: ...: new_student_vec = np.vectorize(new_student) ...: ...: studArr = new_student_vec(["Michael","Rachel"], [1,2]) ...:
With the added repr
the array now prints:
In [4]: studArr Out[4]: array([Student <Michael, 1>, Student <Rachel, 2>], dtype=object)
When you try name
, you get:
In [5]: studArr.name Traceback (most recent call last): File "<ipython-input-5-9248234e8082>", line 1, in <module> studArr.name AttributeError: 'numpy.ndarray' object has no attribute 'name'
You really should have shown this error. Do you understand what’s going on? Just because objects in the array have that attribute, doesn’t mean that the array itself has it.
Consider a list of the same objects. Asking for the name
of the list doesn’t make any sense either.
In [6]: alist = studArr.tolist() In [7]: alist Out[7]: [Student <Michael, 1>, Student <Rachel, 2>] In [8]: alist.name Traceback (most recent call last): File "<ipython-input-8-f77eb3c13383>", line 1, in <module> alist.name AttributeError: 'list' object has no attribute 'name'
You still have to ask each element for that attribute:
In [9]: [s.name for s in alist] Out[9]: ['Michael', 'Rachel']
You could use np.vectorize
, as you did with the constructor, to fetch the attributes (or np.frompyfunc
), but the results, and timings, are basically the same. Using an object array instead of a list has few, if any, advantages.
The idealize “vectorization” only applies to numeric dtypes. The fast compiled code is written in c
using the c
numeric types like floats and doubles. Object dtypes require referencing Python objects in the same way as lists.