Weighted random fetch from 2d numpy array

I have a 2d numpy Z array, and I want to randomly select the index Z, where the probability of choosing an index is proportional to the value of Z in that index.

Now I am doing the following:

yar = list(np.ndenumerate(Z))
x,y = yar[np.random.choice(len(yar), p=Z.ravel()/Z.sum())][0]

Which does the job, but feels disgusting (and extremely slow, besides). Is there a better way?

+4
source share
1 answer

We can optimize while avoiding creation yar. We just get the linear index equivalent from np.random.choice, convert it to dimension indices with np.unravel_index, to give us xand y.

So the implementation will be -

linear_idx = np.random.choice(Z.size, p=Z.ravel()/float(Z.sum()))
x, y = np.unravel_index(linear_idx, Z.shape)

, , yar , -

In [402]: Z = np.random.randint(0,9,(300,400))

In [403]: yar = list(np.ndenumerate(Z))

In [404]: %timeit list(np.ndenumerate(Z))
10 loops, best of 3: 46.3 ms per loop

In [405]: %timeit yar[np.random.choice(len(yar), p=Z.ravel()/float(Z.sum()))][0]
1000 loops, best of 3: 1.34 ms per loop

In [406]: 46.3/(46.3+1.34)
Out[406]: 0.971872376154492

, yar, 97% .

+2

Source: https://habr.com/ru/post/1684381/


All Articles