I define a class Tomato and create an array with several objects of that class:
import numpy as np
class Tomato:
color = None
radius = None
def __init__(self):
color = np.random.choice(['red', 'green'])
radius = np.random.rand()
arr1 = np.array([Tomato() for i in range(6)]).reshape(3, 2)
arr1
yields
array([[<__main__.Tomato object at 0x000002479E7D97F0>,
<__main__.Tomato object at 0x000002479E7D9710>],
[<__main__.Tomato object at 0x000002479E7D94E0>,
<__main__.Tomato object at 0x000002479E7D9DA0>],
[<__main__.Tomato object at 0x000002479E710630>,
<__main__.Tomato object at 0x000002479E7D9C18>]], dtype=object)
I would like to be able to call
arr1.radius
and get a 3x2 array containing just the radius of each tomato. I know I can use np.vectorize() or a lambda expression, as recommended in questions like this one where the asker was working with objects from an externally imported cftime class.
But I believe I should have more options since I defined the Tomato class myself.
For example, the complex128 data type has the methods .real and .imag, and so does an array of complex floats.
arr2 = np.random.normal(size=(3, 2)) + 1j * np.random.normal(size=(3, 2))
arr2.imag
gives you the imaginary part of each entry:
array([[-0.23054982, 0.04599812],
[-0.07459619, -0.11282513],
[-0.32441139, 0.8920348 ]])
Is there a way to modify Tomato's class definition to allow users to access its attributes through a numpy array?
If not, how does the arr2 example above work? Are the .real and .imag methods specified manually in the code for the numpy array class?
numpyis not designed to work with python objects. At least, not efficiently.complex128is just a wrapper type, the primitive numeric type that numpy arrays actually contain aren't actually Python objects. At that point, you might as well just use regular lists. In this case you may actually want to use a structured array, which allows you to work with numpy arrays of primitive structs, where you can write numpy code in terms of the struct's fields.numpyhere?imagandrealattributes. That isn't due to thedtype=complex128.np.linalg.norm) to perform calculations that depend on these attributes, and then update the attributes themselves based on the results of the calculations. But I am also new to the idea of object-oriented programming in general, and just trying to get a feel for what's possible and what's reasonable.numpycode is compiled, usingcnumeric types. Yourarr1contains references to objects stored elsewhere in memory.numpydoes not a mechanism for reaching into your Python code and treat it in a compiled manner.