title: Pythonic way to generate random uniformly distributed points within hollow square lamina
body: <p>Suppose we have a hollow square lamina of size n. That is, we have a nxn square from which a k*l rectangle has been removed (1&lt;=k,l&lt;=n-2). I want to calculate an average of distances between 2 random, uniformly distributed points within such hollow square lamina. 
  For the sake of simplicity let's consider n=3, k=l=1, or a 3x3 square from whose center a unit square has been removed</p>
  
  <p>I wrote this code for numpy, but it has at least 2 problems: I have to throw away approximately 1/9 of all generated points and removing the numpy.array elements requires lots of RAM:</p>
  
  <pre><code>    x,y = 3*np.random.random((2,size,2))
  x = x[
      np.logical_not(np.logical_and(
          np.logical_and(x[:,0] &gt; 1, x[:,0] &lt; 2),
          np.logical_and(x[:,1] &gt; 1, x[:,1] &lt; 2)
          ))
      ]
  y = y[
      np.logical_not(np.logical_and(
          np.logical_and(y[:,0] &gt; 1, y[:,0] &lt; 2),
          np.logical_and(y[:,1] &gt; 1, y[:,1] &lt; 2)
          ))
      ]
  n = min(x.shape[0], y.shape[0])
  </code></pre>
  
  <p>UPD:Here <code>size</code> is the sample size of which I'm going to calculate average. 
  Is there an elegant way to generate those points right away, without removing the unfit ones?</p>
  
  <p>UPD: Here is the full code just for the reference:</p>
  
  <pre><code>def calc_avg_dist(size):
      x,y = 3*np.random.random((2,size,2))
      x = x[
          np.logical_not(np.logical_and(
          np.logical_and(x[:,0] &gt; 1, x[:,0] &lt; 2),
          np.logical_and(x[:,1] &gt; 1, x[:,1] &lt; 2)
          ))
      ]
      y = y[
          np.logical_not(np.logical_and(
          np.logical_and(y[:,0] &gt; 1, y[:,0] &lt; 2),
          np.logical_and(y[:,1] &gt; 1, y[:,1] &lt; 2)
          ))
      ]
      n = min(x.shape[0], y.shape[0])
      diffs = x[:n,:] - y[:n,:]
      return np.sum(np.sqrt(np.einsum('ij,ij-&gt;i',diffs,diffs)))/n
  </code></pre>