numpy.random.choice позволяет взвешенный выбор из вектора, то есть
arr = numpy.array([1, 2, 3])
weights = numpy.array([0.2, 0.5, 0.3])
choice = numpy.random.choice(arr, p=weights) 
выбирает 1 с вероятностью 0,2, 2 с вероятностью 0,5 и 3 с вероятностью 0,3.
Что делать, если мы хотим сделать это быстро в векторном виде для 2D-массива (матрицы), для которого каждая из строк является вектором вероятностей? То есть, мы хотим вектор выбора из стохастической матрицы? Это очень медленный путь:
import numpy as np
m = 10
n = 100 # Or some very large number
items = np.arange(m)
prob_weights = np.random.rand(m, n)
prob_matrix = prob_weights / prob_weights.sum(axis=0, keepdims=True)
choices = np.zeros((n,))
# This is slow, because of the loop in Python
for i in range(n):
    choices[i] = np.random.choice(items, p=prob_matrix[:,i])
 print(choices):
array([ 4.,  7.,  8.,  1.,  0.,  4.,  3.,  7.,  1.,  5.,  7.,  5.,  3.,
        1.,  9.,  1.,  1.,  5.,  9.,  8.,  2.,  3.,  2.,  6.,  4.,  3.,
        8.,  4.,  1.,  1.,  4.,  0.,  1.,  8.,  5.,  3.,  9.,  9.,  6.,
        5.,  4.,  8.,  4.,  2.,  4.,  0.,  3.,  1.,  2.,  5.,  9.,  3.,
        9.,  9.,  7.,  9.,  3.,  9.,  4.,  8.,  8.,  7.,  6.,  4.,  6.,
        7.,  9.,  5.,  0.,  6.,  1.,  3.,  3.,  2.,  4.,  7.,  0.,  6.,
        3.,  5.,  8.,  0.,  8.,  3.,  4.,  5.,  2.,  2.,  1.,  1.,  9.,
        9.,  4.,  3.,  3.,  2.,  8.,  0.,  6.,  1.])
 Этот пост предполагает, что cumsum и bisect могут быть потенциальным подходом и быстро. Но в то время как numpy.cumsum(arr, axis=1) может делать это вдоль одной оси массива numpy, функция bisect.bisect работает только на одном массиве за раз, Аналогично, numpy.searchsorted работает только с 1D-массивами.
Есть ли быстрый способ сделать это, используя только векторизованные операции?
