Ważona losowa próbka w pytonie
Szukam rozsądnej definicji funkcjiweighted_sample
który nie zwraca tylko jednego losowego indeksu dla listy podanych wag (co byłoby czymś w rodzaju
def weighted_choice(weights, random=random):
""" Given a list of weights [w_0, w_1, ..., w_n-1],
return an index i in range(n) with probability proportional to w_i. """
rnd = random.random() * sum(weights)
for i, w in enumerate(weights):
if w<0:
raise ValueError("Negative weight encountered.")
rnd -= w
if rnd < 0:
return i
raise ValueError("Sum of weights is not positive")
dać kategoryczny rozkład ze stałymi wagami), ale losową próbkęk
tych,bez zamiany, tak jakrandom.sample
zachowuje się w porównaniu dorandom.choice
.
Tak jakweighted_choice
można zapisać jako
lambda weights: random.choice([val for val, cnt in enumerate(weights)
for i in range(cnt)])
weighted_sample
może być napisane jako
lambda weights, k: random.sample([val for val, cnt in enumerate(weights)
for i in range(cnt)], k)
ale chciałbym rozwiązanie, które nie wymaga ode mnie odważania na (być może ogromnej) liście.
Edytuj: Jeśli są jakieś ładne algorytmy, które dają mi histogram / listę częstotliwości (w tym samym formacie, co argumentweights
) zamiast sekwencji indeksów byłoby to bardzo przydatne.