On 2012-09-17 11:11, Antonio Piepoli wrote:
Salve a tutti,

premetto che questa domanda è molto stupida ma non riesco a trovare una
soluzione.
Diciamo che ho un vettore la cui lunghezza è già nota a priori. Ogni
elemento del vettore deve subire una funzione; il punto è che la funzione cambia sia da elemento ad elemento ed in generare è scelta con una certa
probabilità.

stavo pensando a qualcosa di questo tipo

first_stage = {'match':0.5, 'unmatch':0.5}
match = ['match_surname','match_name']
unmatch = ['unmatch_surname','unmatch_name']

match_surname = {'1_error':0.5, '2_error':0.3, 'no_error':0.2}
match_name = {'1_error':0.5, '2_error':0.3, 'no_error':0.2}

for record in records:
  destiny = choose(first_stage)
     for step in destiny:
         function = choose(step)
         function(record[desiny.index(record)])

Questo "record[desiny.index(record)]", a parte il typo, non ho capito assolutamente cosa sia. "desiny/destiny" è una lista di due stringhe: che ci fa quell'index(record)? Cos'è records?


la funzione choose prende un dizionario fatto in quel modo e mi restituisce
un valore (stringa):

def choose(d):
    index = -1
    keys = d.keys()
    r = random.random()
    while (r > 0):
          r -= d[keys[index]]
        index += 1
    return keys[index]

Questa funzione non mi sembra funzionare come credi: sembra dipendere dall'ordine delle chiavi, non dal valore associato.


In [30]: vv = [ choose({'1_error':0.5, '2_error':0.3, 'no_error':0.2}) for i in range(10000) ]

    In [31]: len(vv)
    Out[31]: 10000

    In [34]: len([v for v in vv if v == '1_error'])
    Out[34]: 2997

    In [35]: len([v for v in vv if v == '2_error'])
    Out[35]: 2024

    In [36]: len([v for v in vv if v == 'no_error'])
    Out[36]: 4979


posso associare a quella stringa una variabile/funzione con quel nome ? stessa cosa dicasi per i vettori. È una cosa che mi consigliate di fare ?

Nota che in Python puoi usare le funzioni direttamente come oggetti. Puoi scrivere match = [match_surname, match_name], dove prima avevi definito "def match_surname(arg): ...". E poi usare match[0](record) o match[1](record) per richiamare una delle due.

Un trucchetto per scegliere un elemento di una lista con una certa distribuzione potrebbe essere:

    def makedist(items, probs, size=100):
        """La funzione è volutamente non documentata e oneliner
        per spingerti a pensare cosa fa.
        """
return sum(([i] * int(float(p) / sum(probs) * size) for i, p in zip(items, probs)), [])

In [61]: dist = makedist(['1_error', '2_error', 'no_error'], [0.5, 0.3, 0.2])

    In [62]: vv = [ random.choice(dist) for i in range(10000) ]

    In [63]: len([v for v in vv if v == '1_error'])
    Out[63]: 5022

    In [64]: len([v for v in vv if v == '2_error'])
    Out[64]: 3002

    In [65]: len([v for v in vv if v == 'no_error'])
    Out[65]: 1976

Nota, anche qui, che se serve gli elementi in items possono essere funzioni, non stringhe. Quindi se hai una famiglia di funzioni f1, f2, ... associate a probabilità p1, p2, ... puoi fare qualcosa tipo.

    dist = makedist([f1, f2, ...], [p1, p2, ...])

    for record in records:
        random.choice(dist)(record)

--
Daniele Varrazzo - Develer S.r.l.
http://www.develer.com
_______________________________________________
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python

Rispondere a