1

I want to construct a class inheriting from the numpy.ndarray, so that it can do normal operations as a numpy array(+, -, *, /,...). The only thing I want to change is that the way we access the items in our Data. For example:

import numpy as np
from PIL import Image
class Data(np.ndarray):
    """
    Something magical here 
    """

img = np.asarray(Image.open('lena.jpg'))
data = img.view(Data)
data['Red'] #equivalent to img[:,:,0]
normalized_data = data/255. #normalize the data 

Can anyone help me solve this? Thanks and kind regards

Thien95
  • 11
  • 1
  • For a start I'd just a write a function to do the named selection. Latter it could be cast as a Class with its own `get_item` method. Look at `np.lib.index_tricks` for examples. – hpaulj Feb 28 '19 at 19:16

2 Answers2

0

You are going to want to override the __getitem__ method. Here is another question which may provide some intuition: Understanding __getitem__ method.

Link to the docs: https://docs.python.org/3/reference/datamodel.html#object.__getitem__

If you want to change you you set the values, you override __setitem__

An example:

def __getitem__(self, key):
    """ Controls how values are 'gotten'. """
    if key == 'red':
        return self.data[:,:,0]
Ethan Henderson
  • 428
  • 4
  • 11
0

I think you would be better off writing your class from scratch, rather than by extending numpy.ndarray

My reasons:

  1. Since you will be working with non-numeric indices, you are probably going to restrict yourself to 1-dimensional structures. Which means you will be completely ignoring all the multi-dimensional capabilities of numpy.ndarrays.
  2. numpy.ndarray comes with some restrictions such as the fact that the elements must all be of uniform byte-size. Those restrictions may not suit you.

Also, you you might want to take a look at structured arrays of numpy, as they can also be indexed with non-numeric indexes (well, in a certain limited sense, actually -- please go through the examples given there).

Just curious about your desired functionality and semantics: In numpy, if x and y are two 1d numpy arrays of the same length, you are allowed to compare them with x == y. On the other hand, if data_1 and data_2 are two of your arrays, having the same length of 3, they might still be indexed differently. data_1 might be indexed with the index values 'red', 'green', and 'blue', while data_2 might be indexed with values 'high', 'medium', 'low'. In both cases, the number of valid indices is 3, so, in a sense, both data_1 and data_2 are of the same length of 3. But then, would you consider it valid to compare them with data_1 == data_2? What about the array of booleans resulting from the comparison? Would you index the boolean array with 'red', 'green', and 'blue', or with 'high', 'medium', 'low'?

fountainhead
  • 3,584
  • 1
  • 8
  • 17