1

Someone asks the question here: Subclassing numpy ndarray problem but it is basically unanswered.

Here is my version of the question. Suppose you subclass the numpy.ndarray to something that automatically expands when you try to set an element beyond the current shape. You would need to override the setitem and use some numpy.concatenate calls to construct a new array and then assign it to "self" somehow. How to assign the array to "self"?

class myArray(numpy.ndarray):
    def __new__(cls, input_array):
        obj = numpy.asarray(input_array).view(cls)
        return(obj)

    def __array_finalize__(self, obj):
        if obj is None: return

    try:
        super(myArray, self).__setitem__(coords, value)
    except IndexError as e:
        logging.error("Adjusting array")
        ...
        self = new_array # THIS IS WRONG
Community
  • 1
  • 1
mathtick
  • 6,487
  • 13
  • 56
  • 101
  • That assignment to self seems just nonsense, how are you suppsoed to replace an object? Besides, doing such with a numpy array would invalidate views of the array. You just can't do this with a subclass, there is a reason `ndarray.resize` is so restrictive... – seberg Oct 03 '12 at 22:19

1 Answers1

2

Why subclass? Why not just give your wrapper object it's own data member that is an ndarray and use __getitem__ and __setitem__ to operate on the wrapped data member? This is basically what ndarray already does, wrapping Python's built-in containers. Also have a look at Python Pandas which already does a lot of what you're talking about wrapped on top of ndarray.

ely
  • 74,674
  • 34
  • 147
  • 228
  • 1
    Yes, this is what I am currently doing. But then I have to manually wrap all the ndarray (I mean array) attributes and functions that I want to expose to the class right? For example I, I have to implement "__repr__" in the class definition. These are simple, but I thought getting around this was kind of the point of subclassing. Maybe there is another trick? Python Pandas is awesome! I am trying to move towards using it more. – mathtick Oct 04 '12 at 16:43
  • You should just be able to call `MyClass.data.__repr__` if you want the underlying data's `__repr__`. I'd imagine that wrapping it should only require you to do this extra effort for a couple of `ndarray` defaults. Most of your code should not try to do things like `MyClass.sum()` but instead should do `MyClass.data.sum()`, etc... – ely Oct 04 '12 at 16:55