2015-06-13 6 views
5

Ich muss eine zufällige Auswahl mit einer gegebenen Wahrscheinlichkeit treffen, um ein Tupel aus einer Liste auszuwählen.Wie benutze numpy.random.choice in einer Liste von Tupeln?

EDIT: Die probabiliy für jedes Tupel ist in probabilit Liste Ich weiß nicht, den Parameter Ersatz vergessen, die standardmäßig keine ist Das gleiche Problem ein Array statt eine Liste

Der nächste Beispielcode geben Sie mir mit ein Fehler:

import numpy as np 

probabilit = [0.333, 0.333, 0.333] 
lista_elegir = [(3, 3), (3, 4), (3, 5)] 

np.random.choice(lista_elegir, 1, probabilit) 

Und der Fehler ist:

ValueError: a must be 1-dimensional 

Wie kann ich löse das?

+0

Wenn Sie nur Elemente mit gleicher Wahrscheinlichkeit zeichnen möchten, können Sie 'random.choice' aus der Standardbibliothek verwenden. – cel

+0

Ich habe die falsche numpy-Version, so kann ich nicht testen, aber nach [der Dokumentation] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.choice.html#numpy.random .choice), haben Sie versucht, die Liste zu einem "Array" zu machen? Außerdem scheint es, als ob Sie den dritten Parameter 'replace' vermissen. –

Antwort

7

Nach der doc-Funktion,

a : 1-D array-like or int 
    If an ndarray, a random sample is generated from its elements. 
    If an int, the random sample is generated as if a was np.arange(n) 

So folgt,

lista_elegir[np.random.choice(len(lista_elegir),1,p=probabilit)] 

sollte das tun, was Sie wollen. (p= hinzugefügt wie Kommentar; kann weglassen, wenn Werte einheitlich sind).

Es wird eine Zahl aus [0,1,2] ausgewählt und dann dieses Element aus Ihrer Liste ausgewählt.

+0

In Python 3.6 gibt mir das oben einen Fehler beim Sampling mehr als eines Elements: 'Nur Integer-Scaler-Arrays können in einen Scaler-Index konvertiert werden'. Dies wird nicht dadurch gelöst, dass "int" oder "range (len (x))" anstelle von "len (x)" übergeben wird. Eine Lösung besteht darin, eine Inline-for-Schleife zu verwenden: "[x [i] für i in np.choice (len (x), n)]" funktioniert einwandfrei – Scipio

2

Das Problem ist, dass die Liste der Tupel als 2D-Array interpretiert wird, während choice nur mit 1D-Arrays oder ganzen Zahlen funktioniert (interpretiert als "Auswahl aus Bereich"). Siehe the documentation.

Eine Möglichkeit, dies zu beheben, besteht darin, die len der Liste der Tupel zu übergeben und dann die Elemente mit dem entsprechenden Index (oder Indizes) auszuwählen, wie in der other answer beschrieben. Wenn Sie zuerst lista_elegir in eine np.array umwandeln, funktioniert dies auch für mehrere Indizes. zwei weitere Probleme dort sind jedoch:

Zuerst wird die Art und Weise Sie die Funktion aufrufen, wird probabilit als Parameter dritte interpretiert werden, replace, nicht wie die Wahrscheinlichkeiten, dh die Liste als boolean interpretiert Dies bedeutet, dass Sie mit Ersetzung auswählen, aber die tatsächlichen Wahrscheinlichkeiten werden ignoriert. Sie können dies leicht überprüfen, indem Sie den dritten Parameter als [1, 0, 0] übergeben. Verwenden Sie stattdessen p=probabilit. Zweitens müssen die Wahrscheinlichkeiten 1, genau ergeben. Ihre sind nur 0.999. Es scheint, dass Sie die Wahrscheinlichkeiten leicht verzerren müssen, oder lassen Sie einfach diesen Parameter als None, wenn sie alle gleich sind (also gleichmäßige Verteilung annehmend).

>>> probabilit = [0.333, 0.333, 0.333] 
>>> lista_elegir = np.array([(3, 3), (3, 4), (3, 5)]) # for multiple indices 
>>> indices = np.random.choice(len(lista_elegir), 2, p=probabilit if len(set(probabilit)) > 1 else None) 
>>> lista_elegir[indices] 
array([[3, 4], 
     [3, 5]]) 
Verwandte Themen