Subclassing and extending numpy.ndarray

I need some basic representations of the data class, and I want to use the existing numpy classes as they already offer great functionality.

However, I'm not sure if this is the way to do it (although it works so far). So here's an example:

The class Position

should act as simple numpy.array

, but it should display attributes .x

, .y

and .z

for the three components of the array. I have overwritten the method __new__

that returns ndarray

with the original array. To allow access and modification of the array, I defined properties along with settings for each one.

import numpy as np


class Position(np.ndarray):
    """Represents a point in a 3D space

    Adds setters and getters for x, y and z to the ndarray.

    """
    def __new__(cls, input_array=(np.nan, np.nan, np.nan)):
        obj = np.asarray(input_array).view(cls)
        return obj

    @property
    def x(self):
        return self[0]

    @x.setter
    def x(self, value):
        self[0] = value

    @property
    def y(self):
        return self[1]

    @y.setter
    def y(self, value):
        self[1] = value

    @property
    def z(self):
        return self[2]

    @z.setter
    def z(self, value):
        self[2] = value

      

It seems, however, too much code for such basic logic, and I'm wondering if I'll do it the "right" way. I also need a bunch of other classes like Direction

that that will have quite a few other features (auto-norm on change, etc.), and before I start integrating numpy I thought I was asking you ...

+3


source to share


1 answer


I would say ndarray is the wrong choice here, you probably want a simple namedtuple.

>>> import collections
>>> Position = collections.namedtuple('Positions', 'x y z')
>>> p = Position(1, 2, 3)
>>> p
Positions(x=1, y=2, z=3)

      



You can get unboxing this way

>>> x, y, z = p
>>> x, y, z
(1, 2, 3)
>>>

      

+1


source







All Articles