[ Foro de Python ]

Como asigna valores Python? (Sumar dos listas)

13-Nov-2015 20:08
Invitado (deo)
6 Respuestas

No consigo arrancar con Python.
¿Porque no suma los valores float de ix[i] a x[i]?
¿No deberían re-definirse los (int) x como float ?


x  = arange(100)             # asigno valores 0 .. 100
ix = random(100)          # y valores aleatorios 0..1
for i in range(1,100):
    x[i] = x[i-1] + ix[i]       #o simplemente:  x[i] = ix[i] 
x                                          #¿¿  porque no se asignan los valores FLOAT de ix???  


Alguna sugerencia para 'vectorizar' la operacion directamente evitando el 'for'?
Muchas gracias


13-Nov-2015 20:52
Nacho Cabanes (+84)

Tienes un fallo de concepto: "arange" genera una lista, luego puedes extraer elementos individuales de ella con [i]. Por el contrario, "random" (o mejor, "random.random()") genera un único valor real entre 0 y 1, luego no puedes obtener subelementos usando corchetes.


13-Nov-2015 21:20
Invitado (Deo)

Muchas gracias por tu rápida respuesta Nacho.
Es cierto que tengo un fallo de concepto. Y de eso se trata (estoy empezando con Python y creo que para ello debo cambiar la 'mentalidad' del Java/C++);
pero creo que la cosa no es exactamente esa.
Verás:


x  = arange(100)      # crea 100 valores enteros 0 ... 99
x                                 #  muestra correctamente los valores del array x
ix = random(100)    # crea 100 valores aleatorios 0 < ix  < 1
ix                               #  muestra correctamente los valores del array ix

x[3]                            # muestra el valor 3  de x[3]   
ix[3]                           # igualmente muestra el valor concreto de ix[3]   


Pero:
x[3] = ix[3]   # APARENTEMENTE debería asignar a x[3] el valor ix[3]

x[3], ix[3]     # Muestra la lista de dos valores: (0, 0.66345...)

SUPONGO que
convierte el valor a INT antes de asignarlo a x[3] redondeando a la baja, en vez de convertir x[3] a float, y esa es la 'sutileza de Py' que se me escapa.
Tal vez el 'type' de una lista x no puede ser cambiado a posteriori?

Si quiero acumular los valores aleatorios de ix[0] hasta ix[i] en cada x[i] ,..
¿Cual seria la correcta forma de definir x y cual la manera mas correcta de hacerlo?
Gracias de nuevo.


14-Nov-2015 17:17
Nacho Cabanes (+84)

Es que no puedo probarlo, porque no sé qué versión de Python usas ni qué "imports".

Ni en Python 3 ni en Python 2.7 se puede utilizar "random()"como tú lo estás haciendo, generando un array de números al azar. Su uso normal es el que te he puesto, random.random(), que devuelve un único número al azar entre 0 y 1:

https://docs.python.org/2/library/random.html

De igual modo, el uso que yo conozco de "arange" es, como parte de "numpy":


x = numpy.arange(6)


Para generar una serie de números al azar yo usaría random.sample, al que se le indica el rango y la cantidad de valores:


ix = random.sample( xrange(100), 6 )


Necesitarías importar "numpy" y "random". Una vez que tienes dos listas como esas, puedes sumarlas directamente elemento a elemento, sin necesidad de usar "for:


z = x + ix


 


15-Nov-2015 15:51
Invitado (Deo)

Genial, Nacho. Por ahí van los tiros.
Ese 'z = x + ix' que suma ELEMENTO a ELEMENTO es lo que busco.

Pero me esta costando un poco cogerle el puntillo a Python.
Por ejemplo: ¿Porque a mi no me funciona algo como   'z = x + ix' ???

Creo que voy acorralando el problema y estoy impaciente por probar tus sugerentes pistas, que creo que asestarán el golpe definitivo a mi problema;
Pero antes trataré de matizar:
Daba por echo (desde mi ignorancia) que las librerías numpy y pylab son lo habitual y consideré innecesario mencionar los detalles, pero veo que no es así.

from pylab import *
ix = random(50)          # esto es lo que yo usaba para generar aleatorios

Debe ser equivalente a:   ix = numpy.random.random(50) , o rand(50) ¿?

Entonces, prescindiendo de ello el código simplificado quedaría como:

import numpy
from numpy import *
x  = arange(10)
ix = random.random(10)
# y para sumarlos
for i in range(1,10):
 x[i] = x[i] + ix[i]             # simplificando un poco
x                                       # imprimir el resultado

Yo uso Python3 online en Jupyter. Entonces:
try.jupyter.org >> new/Python 3 >>... Ctrl+Enter (para ejecutar cada entrada)

Y el resultado No es lo que espero.
Haré unas pruebas y el resultado en breve... (1h)



15-Nov-2015 16:37
Invitado (Deo)

En efecto, en linea con mi anterior comentario, creo que ya se lo que pasa :

Si reservo espacio con
x = arange(10)   # se reserva como int

#ESTO NO VALE pues x aparece inalterado, ya que random()<1
for i in range(0,10):
 x[i] = x[i] +  random.random()  #x[i] es redondeado a int con el mismo valor


# SIN EMBARGO, esto SI VALE, pues se REASIGNA x (como array de 10 float)
x = x + random.random(10)


TAMBIEN valdría (en ambos casos) haber reservado espacio como:
x = random.random(10)   # ya que se define directamente como floats

# y, QUE FUERTE Python!, TAMBIEN hubiese valido definir inicialmente como:
x = arange(10.)

Un solo puntito...  que me ha robado tres días. Uf, lo daré por bueno si esto evita que le pase a otro!


16-Nov-2015 01:30
Nacho Cabanes (+84)

Por una parte, en cuanto a lo de los "import", sí es necesario detallarlos, porque puede que la biblioteca que tú emplees no sea estándar.

Por otra parte, yo no soy partidario de los "import *", porque pueden provocar colisiones de nombres.

Finalmente, si quieres que "arange" genere datos reales, como bien has descubierto, basta con que el dato límite sea real, pero eso lo puedes ver en la documentación oficial (que es tu amiga ;-D) :

http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.arange.html

Verás que hay un cuarto parámetro opcional, que es el tipo de datos, y en la explicación dice "The type of the output array. If dtype is not given, infer the data type from the other input arguments." Es decir, que si no quieres indicar el tipo de datos de forma explícita, se deducirá de los demás parámetros (en tu caso, sólo uno).






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)