title: subclassing numpy ndarray to simulate padding with zeros on out of bounds indices
body: <p>I want to have a 2D numpy array (NxN) which will return zeros when an index is either negative or out of bounds (i.e. I want to suppress the usual wrap-around indexing that occurs when an index is -1 or the IndexError when your index is N). I could do this literally, simply adding a border of zeros around the array and treating it as a 1-based array instead of a 0-based array, but this seems inelegant. </p>
  
  <p>I stumbled across a few answers here relating to subclassing the numpy ndarray class and defining your own <code>__getitem__</code> attribute. My first attempt looked like this:</p>
  
  <pre><code>import numpy as np
  
  class zeroPaddedArray(np.ndarray):
      def __getitem__(self, index):
          x,y = index
          if x &lt; 0 or y &lt; 0 or x &gt;= self.shape[0] or y &gt;= self.shape[1]:
              return 0
          return super(zeroPaddedArray, self).__getitem__(index)
  </code></pre>
  
  <p>This sort of works, but only allows you to access array elements as <code>arr[x,y]</code>, and throws an error when you try <code>arr[x][y]</code>. It also completely breaks a lot of other functions such as <code>print</code>. <code>print arr</code> gives <code>TypeError: 'int' object is not iterable</code>. </p>
  
  <p>My next attempt was to check if a tuple was given for the index, and to default to the old behavior if not. </p>
  
  <pre><code>import numpy as np
  
  class zeroPaddedArray(np.ndarray):
      def __getitem__(self, index):
          if type(index) is tuple:
              x,y = index
              if x &lt; 0 or y &lt; 0 or x &gt;= self.shape[0] or y &gt;= self.shape[1]:
                  return 0
          return super(zeroPaddedArray, self).__getitem__(index)
      else:
          return super(zeroPaddedArray, self).__getitem__(index)
  </code></pre>
  
  <p>This gives me the requires zero-padding behavior when indexing as a tuple (<code>arr[-1,-1]</code> correctly gives <code>0</code>), but allows other functions to work properly. However, now I get different result depending on the way I index things. For example:</p>
  
  <pre><code>a = np.ones((5,5))
  b = a.view(zeroPaddedArray)
  print b[-1][-1]
  print b[-1,-1]
  </code></pre>
  
  <p>gives </p>
  
  <pre><code>&gt;&gt;&gt;1.0
  &gt;&gt;&gt;0
  </code></pre>
  
  <p>I think this is probably usable as-is for my purposes, but I am unsatisfied. How can I tweak this to give the desired zero-padding behavior regardless of the syntax I use for indexing, without breaking all of the other ndarray functionality?</p>