title: Indexing a NumPy array like a dictionary
body: <p>I need to use a two-dimensional NumPy array for performance reasons, but I also need to be able to index each element. The indices would be <code>models1</code> and <code>models2</code> which subclasses of <code>django.db.models.Model</code>.</p>
  
  <p>I need to be able to get and set items, slice and pass lists of indices, filter, and so on, just as if it were a regular NumPy with integer indices. But I also need to be able to do this using the mentioned indices.</p>
  
  <p>Examples of operations I should be able to do:</p>
  
  <pre><code>arr[m1]
  arr[:,m2]
  arr[(0,1,4),:] = N
  </code></pre>
  
  <p>Is there a standarized way to index NumPy arrays? I haven't been able to find one yet.</p>
  
  <p>I have tried this:</p>
  
  <pre><code>class IndexedArray:
      def __init__(self, models1, models2):
          self.shape = (len(models1), len(models2))
          self.arr = np.full(self.shape, 1)
          self.models1 = [m1 for m1 in models1]
          self.models2 = [m2 for m2 in models2]
          self.model1_indices = {m1: i for i, m1 in enumerate(self.models1)}
          self.model2_indices = {m2: i for i, m2 in enumerate(self.models2)}
  
      def __setitem__(self, key, value):
          if isinstance(key, tuple):
              i = self.models1_indices[key[0]]
              j = self.models2_indices[key[1]]
              self.arr[i, j] = value
          else:
              i = self.models1_indices[key]
              self.arr[i] = value
  
      def __getitem__(self, key):
          if isinstance(key, tuple):
              i = self.models1_indices[key[0]]
              j = self.models2_indices[key[1]]
              return self.arr[i, j]
          i = self.models1_indices[key]
          return self.arr[i]
  
      def get_index(self, o):
          if isinstance(o, Model1):
              return self.models1_indices[o]
          if isinstance(o, Model2):
              return self.models2_indices[o]
          raise TypeError
  </code></pre>
  
  <p>But the number of available operations are limited. I can only get and set <code>arr[m1,m2]</code>, <code>arr[m1]</code> but not <code>arr[:,m2]</code> because slices are not supported (not that they would make sense, but then how can I mass-assign to the second dimension? What should I pass as first index?), and that's about it. Filtering is not supported either...</p>