Re: Presentación y probabilidades
Víctor
victorpernand en gmail.com
Sab Abr 26 20:34:45 CEST 2008
muchas gracias por los consejos, me viene bien enumerate y bisect
scipy tiene muy buena pinta
El día 25 de abril de 2008 14:28, Francesc Altet <faltet en carabos.com>
escribió:
> A Friday 25 April 2008, Víctor escrigué:
> > Hola, un saludo a todos los de la lista. Soy novato en python. Tengo
> > algunas ideas sencillas que me gustaría llevar a la práctica, pero
> > antes tengo que aprender y practicar.
> >
> > Para empezar, estoy intentando hacer una función de permita elegir
> > entre los elementos de una lista, según una lista de probabilidades.
> > Por ejemplo, si le doy la lista ['azul','rojo','verde'] y la lista de
> > probabilidades en tantos por cientos [50,25,25] o en cualquier otra
> > relación como [ 2,1,1] (que sería igual que el anterior), me devuelve
> > uno de los tres colores, según las probabilidades de apararición.
> >
> > Esto es lo que he hecho hasta ahora:
> >
> > from random import randint
> >
> > def sumalista(lista):
> > "suma los elementos de una lista de numeros"
> > return reduce (lambda x,y: x+y, lista)
> >
> > def decide(lista, probab):
> > tmp=[0]
> > for x in range(len(probab)):
> > tmp.append(probab[x]+tmp[x])
> > #normaliza a 1000
> > normaliza= [x*1000/sumalista(probab) for x in tmp]
> >
> > num=randint(0,999)
> > elemento= len([x for x in normaliza if x<=num])-1
> > return lista[elemento]
> >
> >
> > Si hago
> > print decide(['platano','manzana'],[99,1])
> >
> > parece que funciona. ¿Me podéis aconsejar?, y también
> > recomendaciones sobre usar listas de compresion o no, y el estilo
> > python.
>
> Vamos a ello :)
>
> En esta versión:
>
> import bisect
> def decide2(lista, probab):
> tmp=[0]
> for i in range(len(probab)):
> tmp.append(probab[i]+tmp[i])
> #normaliza a 1000
> suma = sum(probab)
> normaliza= [x*1000/suma for x in tmp]
>
> num=randint(0,999)
> elemento= bisect.bisect(normaliza, num)-1
> return lista[elemento]
>
> he hecho lo siguiente:
>
> - En construcciones como "for x in range(...)" es mejor substituir 'x'
> por 'i' que queda más claro que va a usarlo como índice.
>
> - La suma de probabilidades la puedes hacer com la función sum() de
> Python. Como ves, en este caso la he sacado fuera del bucle para no
> repetirla como en la versión original.
>
> - Finalmente, como la lista normaliza está ordenada (por construcción),
> he usado el módulo bisect para hacer búsquedas binarias, que son más
> ràpidas (aunque esto sólo és interesante para lista muuuy largas).
>
> Además, si quisieras hacer uso del paquete de cáculo NumPy, una versión
> más agradable a la vista (y mucho más eficiente) seria:
>
> import numpy
> def decide3(lista, probab):
> probab = numpy.array(probab)
> #normaliza a 1000
> normaliza = probab.cumsum()*1000/probab.sum()
>
> num=numpy.random.randint(1000)
> elemento= normaliza.searchsorted(num)
> return lista[elemento]
>
> Pero esto es ya para un uso avanzado y se deja como ejercicio para el
> lector. Si quieres entenderlo, puedes consultar los manuales de NumPy
> en: http://www.scipy.org/Documentation
>
> Saludos,
>
> --
> >0,0< Francesc Altet http://www.carabos.com/
> V V Cárabos Coop. V. Enjoy Data
> "-"
> _______________________________________________
> Lista de correo Python-es
> http://listas.aditel.org/listinfo/python-es
> FAQ: http://listas.aditel.org/faqpyes
>
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
Más información sobre la lista de distribución Python-es