0
import numpy as np

origin = np.arange(12).reshape(4, 3)
"""
[0 1 2
 3 4 5
 6 7 8
 9 10 11]
"""

subset = origin[1:3, :2]
"""
[3 4
 6 7]
"""

How can I get index slices [1, 2] and [0, 1] given subset and origin assuming subset are contiguous part of origin? What if it's not contiguous?

Background: I'm learning subclassing of np.ndarray, and want to and index and columns label on it (similar as pd.DataFrame but not as robust as it). When dealing with slicing by __array_finalize__ method, I have to get the index slices of self(subset) from obj(origin), and set corresponding subset of index and columns to new object.

import numpy as np

class InfoArray(np.ndarray):
   def __new__(cls, input_array, index=[], columns=[]):
      obj = np.asarray(input_array).view(cls)
      obj.index = index
      obj.columns = columns
      return obj

   def __array_finalize__(self, obj):
      if obj is None:
         return
      """
      index_slice, columns_slice = get_slice(self, obj).  # todo
      self.index = obj.index[index_slice]
      self.columns = obj.columns[columns_slice]
      """


LeonM
  • 23
  • 1
  • 6

1 Answers1

0
In [39]: origin = np.arange(12).reshape(4, 3)
In [40]: subset = origin[1:3, :2]

For these two array, a good summary of their attributes is:

In [41]: origin.__array_interface__
Out[41]: 
{'data': (94084725414528, False),
 'strides': None,
 'descr': [('', '<i8')],
 'typestr': '<i8',
 'shape': (4, 3),
 'version': 3}
In [42]: subset.__array_interface__
Out[42]: 
{'data': (94084725414552, False),
 'strides': (24, 8),
 'descr': [('', '<i8')],
 'typestr': '<i8',
 'shape': (2, 2),
 'version': 3}
In [43]: origin.strides
Out[43]: (24, 8)

Since the indexing has step size 1, the strides are the same. A view that changes strides might look like:

In [44]: origin[::2,:2].strides
Out[44]: (48, 8)

The 'data' "pointer" starts 24 bytes further, that's 3 elements, or from the strides, one row. With that, and shape we can deduce that the slicing was

[1:1+2, 0:0+2]

I'll leave the details and generalization to you, but this may be enough to get you started.

hpaulj
  • 221,503
  • 14
  • 230
  • 353