Python: более быстрая альтернатива numpy's random.choice ()? - PullRequest
0 голосов
/ 27 мая 2018

Я пытаюсь выбрать 1000 чисел от 0 до 999, с вектором весов, определяющим вероятность того, что будет выбрано конкретное число:

import numpy as np
resampled_indices = np.random.choice(a = 1000, size = 1000, replace = True, p = weights)

К сожалению, этот процесс должен выполняться тысячамираз в большей для цикла, и кажется, что np.random.choice является узким местом основной скорости в процессе.Поэтому мне было интересно, есть ли способ ускорить np.random.choice или использовать альтернативный метод, который дает такие же результаты.

1 Ответ

0 голосов
/ 26 января 2019

Кажется, что вы можете сделать немного быстрее, используя равномерную выборку, а затем "инвертировать" кумулятивное искажение, используя np.searchsorted:

# assume arbitrary probabilities
weights = np.random.randn(1000)**2
weights /= weights.sum()

def weighted_random(w, n):
    cumsum = np.cumsum(w)
    rdm_unif = np.random.rand(n)
    return np.searchsorted(cumsum, rdm_unif)

# first method
%timeit np.random.choice(a = 1000, size = 1000, replace = True, p = weights)
# 10000 loops, best of 3: 220 µs per loop

# proposed method
%timeit weighted_random(weights, n)
# 10000 loops, best of 3: 158 µs per loop

Теперь мы можем эмпирически проверить, что вероятности верны:

samples =np.empty((10000,1000),dtype=int)
for i in xrange(10000):
    samples[i,:] = weighted_random(weights)

empirical = 1. * np.bincount(samples.flatten()) / samples.size
((empirical - weights)**2).max()
# 3.5e-09
...