title: Vectorizing for-loops with numpy
body: <p>Function in question is <code>rs</code>, and the <code>groups</code> and <code>difference</code> functions that are used in <code>rs</code>:</p>
  <pre><code>def groups(I, mask):
      grp=[]
      m, n = I.shape 
      x, y = np.abs(mask).shape
      for i in range(m-x):
          for j in range(n-y):
              grp.append(I[i:(i+x), j:(j+y)])
      return grp
  # }}}
  
  # {{{ difference()
  def difference(I, mask):
      cmask = - mask
      cmask[(mask &gt; 0)] = 0
      L = []
      for g in groups(I, mask):
          flip = (g + cmask) ^ np.abs(mask) - cmask
          L.append(np.sign(smoothness(flip) - smoothness(g)))
      N = len(L)
      R = float(L.count(1))/N
      S = float(L.count(-1))/N
      return R-S
  # }}}
  
  # {{{ rs()
  def rs(filename, channel=0):
      I = imread(filename)
      if channel!=None:
          I = I[:,:,channel]
      I = I.astype(int)
  
      mask = np.array( [[1,0],[0,1]] )
      d0 = difference(I, mask)
      d1 = difference(I^1, mask)
  
      mask = -mask
      n_d0 = difference(I, mask)
      n_d1 = difference(I^1, mask)
  
      p0, p1 = solve(2*(d1+d0), (n_d0-n_d1-d1-3*d0), (d0-n_d0)) 
      if np.abs(p0) &lt; np.abs(p1): 
          z = p0
      else: 
          z = p1
  
      return z / (z-0.5)
  # }}}
  </code></pre>
  <p>If you need to see more code, it's at: <a href="https://github.com/daniellerch/aletheia/blob/master/aletheialib/attacks.py" rel="nofollow noreferrer">https://github.com/daniellerch/aletheia/blob/master/aletheialib/attacks.py</a></p>
  <p>As you can see, there are many for-loops within each. <code>rs</code> takes minutes to complete. <code>spa</code> used to take just as long, but a contributor sped it up using vectorization (and now <code>spa</code> takes a few seconds to complete).</p>
  <p>I only know a bit about vectorization from working through machine learning tutorials. I've never put it into practice. Can anyone help on this front? Thanks in advance.</p>