Random sampling without replacement when more needs to be sampled than there are samples
<p>I need to generate samples from a list of numbers in a scenario where I might have the situation that I need to sample more numbers than I have. More explicitly, this is what I need to do: </p>

<ul>
<li><p>Let the total number of elements in my list be N.</p></li>
<li><p>I need to sample randomly without replacement from this list M samples.</p></li>
<li><p>If M &lt;= N, then simply use Numpy's random.choice without replacement. </p></li>
<li><p>If M > N, then the samples must consist X times all the N numbers in the list, where X is the number of times N fully divides M, i.e. X = floor(M/N) and then sample additional M-(X*N) remainder samples from the list without replacement. </p></li>
</ul>

<p>For example, let my list be the following: </p>

<blockquote>
  <p>L = [1, 2, 3, 4, 5]</p>
</blockquote>

<p>and I need to sample 8 samples. Then firstly, I sample the full list once and additional 3 elements randomly without replacement, e.g. my samples could then be: </p>

<blockquote>
  <p>Sampled_list = [1, 2, 3, 4, 5, 3, 5, 1]</p>
</blockquote>

<p>How can I implement such a code as efficiently as possible in terms of computation time in Python? Can this be done without for-loops? </p>

<p>At the moment I'm implementing this using for-loops but this is too inefficient for my purposes. I have also tried Numpy's random.choice without replacement but then I need to have M &lt;= N. </p>

<p>Thank you for any help! </p>

<p>You can <a href="http://docs.scipy.org/doc/numpy/reference/generated/numpy.concatenate.html" rel="nofollow"><code>concatenate</code></a> the results of <a href="http://docs.scipy.org/doc/numpy/reference/generated/numpy.repeat.html" rel="nofollow"><code>repeat</code></a> and <a href="http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.choice.html#numpy.random.choice" rel="nofollow"><code>random.choice</code></a>:</p>

<pre><code>np.concatenate((np.repeat(L, M // len(L)), np.random.choice(L, M - M // len(L))))
</code></pre>

<p>First, the sequence is repeated as often as necessary, then a choice is made for the remaining number needed; finally, the two arrays are concatenated.</p>

<p>Note that you can easily determine whether <code>choice</code> works with replacement or without, using the <a href="http://docs.scipy.org/doc/numpy-dev/reference/generated/numpy.random.choice.html" rel="nofollow"><code>replace</code> parameter</a>:</p>

<blockquote>
  <p><strong>replace</strong> : boolean, optional --
  Whether the sample is with or without replacement</p>
</blockquote>

python numpy sampling