Python numpy: convierte una cadena en una matriz numpy

Tengo la siguiente cadena que he puesto juntos:

v1fColor = '2,4,14,5,0,0,0,0,0,0,0,0,0,0,12,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,6,0,0,0,0,1,0,0,0,0,0,0,0,0,0,20,9,0,0,0,2,2,0,0,0,0,0,0,0,0,0,13,6,0,0,0,1,0,0,0,0,0,0,0,0,0,0,10,8,0,0,0,1,2,0,0,0,0,0,0,0,0,0,17,17,0,0,0,3,6,0,0,0,0,0,0,0,0,0,7,5,0,0,0,2,0,0,0,0,0,0,0,0,0,0,4,3,0,0,0,1,1,0,0,0,0,0,0,0,0,0,6,6,0,0,0,2,3' 

Lo estoy tratando como un vector: cuento largo es un color de un histogtwig de imagen:

Tengo la siguiente función lambda para calcular la similitud de coseno de dos imágenes, así que traté de convertir esto es a numpy.array pero fallé:

Aquí está mi función lambda

 import numpy as NP import numpy.linalg as LA cx = lambda a, b : round(NP.inner(a, b)/(LA.norm(a)*LA.norm(b)), 3) 

Así que intenté lo siguiente para convertir esta cadena como una matriz numpy:

 v1fColor = NP.array([float(v1fColor)], dtype=NP.uint8) 

Pero terminé recibiendo el siguiente error:

  v1fColor = NP.array([float(v1fColor)], dtype=NP.uint8) ValueError: invalid literal for float(): 2,4,14,5,0,0,0,0,0,0,0,0,0,0,12,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,6,0,0,0,0,1,0,0,0,0,0,0,0,0,0,20,9,0,0,0,2,2,0,0,0,0,0,0,0,0,0,13,6,0,0,0,1,0,0,0,0,0,0,0,0,0,0,10,8,0,0,0,1,2,0,0,0,0,0,0,0,0,0,17,17, 

Tienes que dividir la cadena por sus comas primero:

 NP.array(v1fColor.split(","), dtype=NP.uint8) 

Puede hacer esto sin usar los métodos de cadena de python; intente numpy.fromstring :

 >>> numpy.fromstring(v1fColor, dtype='uint8', sep=',') array([ 2, 4, 14, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 6, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 9, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 8, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 3, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 2, 3], dtype=uint8) 

Puedes hacerlo:

 lst = v1fColor.split(',') #create a list of strings, splitting on the commas. v1fColor = NP.array( lst, dtype=NP.uint8 ) #numpy converts the strings. Nifty! 

o más concisamente:

 v1fColor = NP.array( v1fColor.split(','), dtype=NP.uint8 ) 

Tenga en cuenta que es un poco más habitual hacer:

 import numpy as np 

en comparación con la import numpy as NP

EDITAR

Hoy mismo aprendí sobre la función numpy.fromstring que también podría usarse para resolver este problema:

 NP.fromstring( "1,2,3" , sep="," , dtype=NP.uint8 ) 

Estoy escribiendo esta respuesta, así que para futuras referencias: no estoy seguro de cuál es la solución correcta en este caso, pero creo que lo que @David Robinson publicó inicialmente fue la respuesta correcta debido a una razón: los valores de similitud de coseno no pueden ser mayores que una y cuando uso la NP.array(v1fColor.split(","), dtype=NP.uint8) obtengo valores de strage que están por encima de 1.0 para la similitud de coseno entre dos vectores.

Así que escribí un código de muestra simple para probar:

 import numpy as np import numpy.linalg as LA def testFunction(): value1 = '2,3,0,80,125,15,5,0,0,0,0,0,0,0,0,0,0,0,0,0,2,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' value2 = '2,137,0,4,96,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' cx = lambda a, b : round(np.inner(a, b)/(LA.norm(a)*LA.norm(b)), 3) #v1fColor = np.array(map(int,value1.split(','))) #v2fColor = np.array(map(int,value2.split(','))) v1fColor = np.array( value1.split(','), dtype=np.uint8 ) v2fColor = np.array( value2.split(','), dtype=np.uint8 ) print v1fColor print v2fColor cosineValue = cx(v1fColor, v2fColor) print cosineValue if __name__ == '__main__': testFunction() 

Si ejecuta este código, debería obtener la siguiente salida: introduzca la descripción de la imagen aquí

No permite comentar dos líneas y ejecutar el código con la Solución inicial de David:

 v1fColor = np.array(map(int,value1.split(','))) v2fColor = np.array(map(int,value2.split(','))) 

Tenga en cuenta que, como se ve más arriba, el valor de similitud de coseno subió por encima de 1.0, pero cuando usamos la función de mapa y hacemos el lanzamiento int, obtenemos el siguiente valor, que es el valor correcto:

introduzca la descripción de la imagen aquí

Afortunadamente, estaba trazando los valores que estaba obteniendo inicialmente y algunos de los valores de coseno superaban los 1.0, tomé los resultados de estos vectores y los escribí manualmente en la consola de Python, los envié a través de mi función lambda y obtuve la respuesta correcta, así que Fue muy confuso. Luego escribí el guión de prueba para ver qué sucede y me alegro de haber detectado este problema. No soy un experto en python para decir exactamente lo que está sucediendo en dos métodos para dar dos respuestas diferentes. Pero eso se lo dejo a @David Robinson o @mgilson.