2015-06-13 13 views
5

Ho bisogno di fare una scelta casuale con una probabilità data per selezionare una tupla da una lista.Come usare numpy.random.choice in un elenco di tuple?

EDIT: Il probabiliy per ogni tupla è nella lista probabilit non so dimenticare la sostituzione dei parametri, per impostazione predefinita è nessuno Lo stesso problema utilizzando una matrice invece un elenco

Il codice di esempio successivo mi danno un errore:

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) 

e l'errore è:

ValueError: a must be 1-dimensional 

Come può lo risolvo?

+0

Se si desidera disegnare elementi con uguale probabilità, è possibile utilizzare 'random.choice 'dalla lib standard. – cel

+0

Ho la versione numpy sbagliata, quindi non posso testare, ma secondo [la documentazione] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.choice.html#numpy.random .choice), hai provato a rendere la lista una 'matrice' numerica? Inoltre, sembra che manchi il terzo parametro 'replace'. –

risposta

7

Secondo doc della funzione,

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) 

Così successivo

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

dovrebbe fare quello che vuoi. (p= aggiunto come per commento, può omettere se i valori sono uniformi).

Sta scegliendo un numero da [0,1,2], quindi selezionando tale elemento dall'elenco.

+0

In Python 3.6, quanto sopra mi dà un errore durante il campionamento di più di un elemento: 'solo gli array di scaler interi possono essere convertiti in un indice di scaler'. Questo non è risolto con il cast di 'int' o usando' range (len (x)) 'invece di' len (x) '. Una soluzione è usare un loop inline for: '[x [i] per i in np.choice (len (x), n)]' funziona bene – Scipio

2

Il problema è che l'elenco di tuple è interpretato come un array 2D, mentre choice funziona solo con array 1D o interi (interpretati come "scegli dall'intervallo"). Vedi the documentation.

Quindi, un modo per risolvere questo problema è passare lo len dell'elenco di tuple e quindi selezionare gli elementi con il rispettivo indice (o indici), come descritto nello other answer. Se si attiva lista_elegir in un np.array, questo funzionerà anche per più indici. Tuttavia, ci sono due problemi:

In primo luogo, il modo in cui si richiama la funzione, probabilit saranno interpretati come parametro terzo, replace, non come le probabilità, vale a dire, la lista viene interpretato come un valore booleano , significa che scegli con la sostituzione, ma le probabilità effettive vengono ignorate. È possibile controllare facilmente passando il terzo parametro come [1, 0, 0]. Utilizzare invece p=probabilit. In secondo luogo, le probabilità devono riassumere fino a 1, esattamente. I tuoi sono solo 0.999. Sembra che dovrai modificare leggermente le probabilità o lasciare tale parametro come None se sono tutte uguali (assumendo quindi una distribuzione uniforme).

>>> 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]]) 
Problemi correlati