Ich habe eine Datei mit einigen Wahrscheinlichkeiten für verschiedene Werte, z.
1 0.1
2 0.05
3 0.05
4 0.2
5 0.4
6 0.2
Ich möchte mit dieser Verteilung Zufallszahlen generieren. Gibt es ein vorhandenes Modul, das dies behandelt? Es ist ziemlich einfach, selbst zu codieren (die kumulative Dichtefunktion erstellen, einen zufälligen Wert [0,1] generieren und den entsprechenden Wert auswählen), aber es scheint, dass dies ein häufiges Problem sein sollte und wahrscheinlich jemand eine Funktion / ein Modul für erstellt hat es.
Ich brauche das, weil ich eine Liste von Geburtstagen erstellen möchte (die keiner Verteilung im Standardmodul folgen random
).
random.choice()
? Sie erstellen die Hauptliste mit der richtigen Anzahl von Vorkommen und wählen eines aus. Dies ist natürlich eine doppelte Frage.Antworten:
scipy.stats.rv_discrete
könnte sein, was Sie wollen. Sie können Ihre Wahrscheinlichkeiten über denvalues
Parameter angeben. Sie können dann diervs()
Methode des Verteilungsobjekts verwenden, um Zufallszahlen zu generieren.Wie Eugene Pakhomov in den Kommentaren hervorhob, können Sie auch einen
p
Schlüsselwortparameter annumpy.random.choice()
zWenn Sie Python 3.6 oder höher verwenden, können Sie es
random.choices()
aus der Standardbibliothek verwenden - siehe die Antwort von Mark Dickinson .quelle
numpy.random.choice()
ist fast 20 mal schneller.numpy.random.choice(numpy.arange(1, 7), p=[0.1, 0.05, 0.05, 0.2, 0.4, 0.2])
Seit Python 3.6 gibt es dafür eine Lösung in der Standardbibliothek von Python, nämlich
random.choices
.Anwendungsbeispiel: Lassen Sie uns eine Grundgesamtheit und Gewichte einrichten, die denen in der Frage des OP entsprechen:
choices(population, weights)
Generiert jetzt eine einzelne Stichprobe:Mit dem optionalen Argument "Nur Schlüsselwörter"
k
können mehrere Beispiele gleichzeitig angefordert werden. Dies ist wertvoll, darandom.choices
jedes Mal, wenn es aufgerufen wird, einige Vorbereitungsarbeiten durchgeführt werden müssen, bevor Proben generiert werden. Durch die gleichzeitige Erzeugung vieler Proben müssen wir diese Vorbereitungsarbeiten nur einmal durchführen. Hier generieren wir eine Million Proben undcollections.Counter
überprüfen, ob die Verteilung, die wir erhalten, ungefähr mit den von uns angegebenen Gewichten übereinstimmt.quelle
Ein Vorteil beim Generieren der Liste mit CDF besteht darin, dass Sie die binäre Suche verwenden können. Während Sie O (n) Zeit und Raum für die Vorverarbeitung benötigen, können Sie k Zahlen in O (k log n) erhalten. Da normale Python-Listen ineffizient sind, können Sie das
array
Modul verwenden.Wenn Sie auf konstantem Platz bestehen, können Sie Folgendes tun: O (n) Zeit, O (1) Raum.
quelle
l[-1]
das letzte Element der Liste zurückgegeben wird?Vielleicht ist es schon spät. Sie können jedoch Folgendes verwenden
numpy.random.choice()
, indem Sie denp
Parameter übergeben:quelle
random.choice()
- siehe Kommentare.numpy.random.choice()
ist völlig andersrandom.choice()
und unterstützt die Wahrscheinlichkeitsverteilung.(OK, ich weiß, dass Sie nach Schrumpffolie fragen, aber vielleicht waren diese selbst entwickelten Lösungen einfach nicht prägnant genug für Ihren Geschmack. :-)
Ich habe pseudo-bestätigt, dass dies funktioniert, indem ich die Ausgabe dieses Ausdrucks musterte:
quelle
i
ist kein Objekt.Ich habe eine Lösung zum Zeichnen von Zufallsstichproben aus einer benutzerdefinierten kontinuierlichen Verteilung geschrieben .
Ich brauchte dies für einen ähnlichen Anwendungsfall wie Ihren (dh das Generieren von zufälligen Daten mit einer bestimmten Wahrscheinlichkeitsverteilung).
Sie brauchen nur die Funktion
random_custDist
und die Leitungsamples=random_custDist(x0,x1,custDist=custDist,size=1000)
. Der Rest ist Dekoration ^^.Die Leistung dieser Lösung ist sicher verbesserungsfähig, aber ich bevorzuge die Lesbarkeit.
quelle
Erstellen Sie eine Liste mit Elementen, basierend auf
weights
:Eine Optimierung kann darin bestehen, Beträge durch den größten gemeinsamen Teiler zu normalisieren, um die Zielliste kleiner zu machen.
Auch das könnte interessant sein.
quelle
Eine andere Antwort, wahrscheinlich schneller :)
quelle
Überprüfung:
quelle
Basierend auf anderen Lösungen generieren Sie eine kumulative Verteilung (als Ganzzahl oder Float, was auch immer Sie möchten). Anschließend können Sie die Halbierung verwenden, um sie schnell zu machen
Dies ist ein einfaches Beispiel (ich habe hier ganze Zahlen verwendet)
Die
get_cdf
Funktion würde es von 20, 60, 10, 10 in 20, 20 + 60, 20 + 60 + 10, 20 + 60 + 10 + 10 konvertierenJetzt wählen wir eine Zufallszahl bis zu 20 + 60 + 10 + 10 aus und verwenden
random.randint
dann die Halbierung, um den tatsächlichen Wert schnell zu erhaltenquelle
Vielleicht möchten Sie einen Blick auf NumPy Random Sampling Distributionen werfen
quelle
Keine dieser Antworten ist besonders klar oder einfach.
Hier ist eine klare, einfache Methode, die garantiert funktioniert.
accumulate_normalize_probabilities verwendet ein Wörterbuch
p
, das Symbole Wahrscheinlichkeiten ODER Frequenzen zuordnet . Es gibt eine verwendbare Liste von Tupeln aus, aus denen ausgewählt werden kann.Ausbeuten:
Warum es funktioniert
Die Akkumulation verwandelt jedes Symbol in ein Intervall zwischen sich und der Wahrscheinlichkeit oder Häufigkeit der vorherigen Symbole (oder 0 im Fall des ersten Symbols). Diese Intervalle können verwendet werden, um aus der Liste auszuwählen (und damit die bereitgestellte Verteilung abzutasten), indem Sie einfach durch die Liste gehen, bis die Zufallszahl in Intervall 0.0 -> 1.0 (zuvor vorbereitet) kleiner oder gleich dem Intervallendpunkt des aktuellen Symbols ist.
Das Normalisierung befreit uns von der Notwendigkeit, sicherzustellen, dass alles einen gewissen Wert hat. Nach der Normalisierung summiert sich der "Vektor" der Wahrscheinlichkeiten auf 1,0.
Der Rest des Codes zum Auswählen und Generieren einer beliebig langen Stichprobe aus der Verteilung ist unten aufgeführt:
Verwendung :
quelle
Hier ist ein effektiverer Weg , dies zu tun:
Rufen Sie einfach die folgende Funktion mit Ihrem 'Gewichte'-Array (unter der Annahme, dass die Indizes die entsprechenden Elemente sind) und der Nr. Auf. von Proben benötigt. Diese Funktion kann leicht geändert werden, um geordnete Paare zu handhaben.
Gibt Indizes (oder Artikel) zurück, die mit ihren jeweiligen Wahrscheinlichkeiten abgetastet / ausgewählt wurden (mit Ersatz):
Ein kurzer Hinweis zum Konzept der while-Schleife. Wir reduzieren das Gewicht des aktuellen Artikels aus dem kumulativen Beta, einem kumulativen Wert, der gleichmäßig zufällig erstellt wird, und erhöhen den aktuellen Index, um den Artikel zu finden, dessen Gewicht mit dem Beta-Wert übereinstimmt.
quelle