numpy.random.choice
permette la selezione ponderata da un vettore, cioèrapida Selezione ponderata casuale lungo tutte le righe di una matrice stocastica
arr = numpy.array([1, 2, 3])
weights = numpy.array([0.2, 0.5, 0.3])
choice = numpy.random.choice(arr, p=weights)
seleziona 1 con probabilità 0.2, 2 con probabilità 0.5 e 3 con probabilità 0.3.
E se volessimo farlo rapidamente in modo vettorizzato per un array 2D (matrice) per il quale ciascuna delle righe è un vettore di probabilità? Cioè, vogliamo un vettore di scelte da una matrice stocastica? Questo è il modo super lento:
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.])
This post suggerisce che cumsum
e bisect
potrebbe essere un potenziale approccio, ed è veloce. Ma mentre lo numpy.cumsum(arr, axis=1)
può farlo lungo un asse di un array numpy, la funzione bisect.bisect
funziona solo su un singolo array alla volta. Allo stesso modo, numpy.searchsorted
funziona anche su array 1D.
C'è un modo rapido per farlo utilizzando solo le operazioni vettorializzate?
Ottima risposta! Per quanto riguarda il tuo commento iniziale, non penso che tu possa persino fare un 'searchsorted 'vettorizzato su un array 2D, vero? Quindi sarà comunque lento. –
Intendo 'searchsorted' utilizzato in un ciclo, come nella funzione' improved'. Per 'm' sufficientemente grande, la migliore complessità temporale del codice in' improved' (anche con il suo loop python lento) supererà la soluzione 'vectorized'. –