Frage

Ich habe eine Reihe von Elementwahrscheinlichkeiten, sagen wir mal [0.1, 0.2, 0.5, 0.2].Das Array summiert sich auf 1,0.

Mit einfachem Python oder Numpy möchte ich Elemente proportional zu ihrer Wahrscheinlichkeit zeichnen:das erste Element etwa 10 % der Zeit, das zweite 20 %, das dritte 50 % usw.Die „Zeichnung“ sollte den Index des gezeichneten Elements zurückgeben.

Ich habe mir Folgendes ausgedacht:

def draw(probs):
    cumsum = numpy.cumsum(probs / sum(probs)) # sum up to 1.0, just in case
    return len(numpy.where(numpy.random.rand() >= cumsum)[0])

Es funktioniert, aber es ist zu kompliziert, es muss einen besseren Weg geben.Danke.

War es hilfreich?

Lösung

import numpy as np
def random_pick(choices, probs):
    '''
    >>> a = ['Hit', 'Out']
    >>> b = [.3, .7]
    >>> random_pick(a,b)
    '''
    cutoffs = np.cumsum(probs)
    idx = cutoffs.searchsorted(np.random.uniform(0, cutoffs[-1]))
    return choices[idx]

Wie es funktioniert:

In [22]: import numpy as np
In [23]: probs = [0.1, 0.2, 0.5, 0.2]

Berechnen Sie die kumulative Summe:

In [24]: cutoffs = np.cumsum(probs)
In [25]: cutoffs
Out[25]: array([ 0.1,  0.3,  0.8,  1. ])

Berechnen Sie eine gleichmäßig verteilte Zufallszahl im halboffenen Intervall [0, cutoffs[-1]):

In [26]: np.random.uniform(0, cutoffs[-1])
Out[26]: 0.9723114393023948

Verwenden suchsortiert um den Index zu finden, in den die Zufallszahl eingefügt werden würde cutoffs:

In [27]: cutoffs.searchsorted(0.9723114393023948)
Out[27]: 3

Zurückkehren choices[idx], Wo idx ist dieser Index.

Andere Tipps

Sie möchten aus der kategorialen Verteilung proben, die nicht in numpy implementiert ist.Die Multinomial Verteilung ist eine Verallgemeinerung des kategoriale -Verteilung und kann für diesen Zweck verwendet werden. generasacodicetagpre.

numpy.random.multinomial - am effizientesten

Ich habe noch nie KUMPY benutzt, aber ich gehe davon aus, dass mein Code unten (nur Python) das Gleiche tut, was Sie in einer Zeile erreicht haben.Ich setze es hier nur für den Fall, dass Sie es wollen.

sieht sehr c-ish aus, also entschuldige mich, dass es nicht sehr pythonisch ist.

weight_total wäre für Sie 1 für Sie. generasacodicetagpre.

Verwenden Sie bisect generasacodicetagpre.

sollte den Trick tun.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top