title: Numpy efficient way to get adiacent indices or values in matrices
body: <p>Say you have a matrix A with strings in it.</p>
  
  <pre><code>[["a", "A", ""],
   ["A", "a", ""],
   ["a", "", ""]]
  </code></pre>
  
  <p>The objective is to find all the "squares" where there are orthogonal adjacent upper case letters and no orthogonal adjacent lower case letters.
  The result should be like this:</p>
  
  <pre><code>[[True, False, True],
   [False, True, False],
   [True, False, False]]
  </code></pre>
  
  <p>Now, what I have done until now was to create a dictionary adjSquares that links the cartesian indices of each square with the cartesian indices of the adiacent squares.</p>
  
  <p>Every time I have to make the check described above I do the following:</p>
  
  <pre><code>np.reshape([any(isupper(A[i,j] for (i,j) in adjSquares[(row,col)])) and not any(islower(A[i,j] for (i,j) in adjSquares[(row,col)])) for row in range(3) for col in range(3)], (3,3))
  </code></pre>
  
  <p>Is there a way to get the same result using vectorized operations?</p>