Efficient use of numpy.random.choice with repeated numbers and alternatives
<p>I need to generate a large array with repeated elements, and my code is:</p>

<pre><code>np.repeat(xrange(x,y), data)
</code></pre>

<p>However, data is a numpy array with type float64 (but it represent integeres, no 2.1 there) and I get the error</p>

<pre><code>TypeError: Cannot cast array data from dtype('float64') to dtype('int64') according to the rule 'safe'
</code></pre>

<p>Exemple:</p>

<pre><code>In [35]: x
Out[35]: 26

In [36]: y
Out[36]: 50

In [37]: data
Out[37]: 
array([ 3269.,   106.,  5533.,   317.,  1512.,   208.,   502.,   919.,
     406.,   421.,  1690.,  2236.,   705.,   505.,   230.,   213.,
     307.,  1628.,  4389.,  1491.,   355.,   103.,   854.,   424.])
In [38]: np.repeat(xrange(x,y), data)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call    last)
&lt;ipython-input-38-105860821359&gt; in &lt;module&gt;()
----&gt; 1 np.repeat(xrange(x,y), data)

/home/pcadmin/anaconda2/lib/python2.7/site-packages/numpy    /core/fromnumeric.pyc in repeat(a, repeats, axis)
394         repeat = a.repeat
395     except AttributeError:
--&gt; 396         return _wrapit(a, 'repeat', repeats, axis)
397     return repeat(repeats, axis)
398 

/home/pcadmin/anaconda2/lib/python2.7/site-packages/numpy  /core/fromnumeric.pyc in _wrapit(obj, method, *args, **kwds)
 46     except AttributeError:
 47         wrap = None
---&gt; 48     result = getattr(asarray(obj), method)(*args, **kwds)
 49     if wrap:
 50         if not isinstance(result, mu.ndarray):

TypeError: Cannot cast array data from dtype('float64') to dtype('int64') according to the rule 'safe'
</code></pre>

<p>I solve it by changing the code to</p>

<pre><code>np.repeat(xrange(x,y), data.astype('int64'))
</code></pre>

<p>However, this is now one of the most expensive lines in my code!! Is there another alternative?</p>

<p>By the way, I using this inside</p>

<pre><code>np.random.choice(np.repeat(xrange(x,y), data.astype('int64')), z)
</code></pre>

<p>in order to get a sample without replacement with size z of the integers between x and y, with the number of each given in data. I guess this is the best approach for that also right?</p>

<p>For completion, I also have an alternative implementation. Given that we have <code>data</code>, we can use an hypergeometric sampling for each class:</p>

<ul>
<li>calculate reverse <code>data.cumsum()</code></li>
<li>for each class draw <code>np.hypergeometric(data[pos], cumsum[pos]-data[pos], remain)</code></li>
</ul>

<p>However, when we have many classes with few units in each this takes a long time.</p>

python python-2.7 numpy casting repeat