Agregue programáticamente los nombres de columna a ndarray numpy

Estoy tratando de agregar nombres de columna a una ndarray numpy, luego seleccionar columnas por sus nombres. Pero no funciona. No puedo saber si el problema se produce cuando agrego los nombres o, más tarde, cuando bash llamarlos.

Aquí está mi código.

data = np.genfromtxt(csv_file, delimiter=',', dtype=np.float, skip_header=1) #Add headers csv_names = [ s.strip('"') for s in file(csv_file,'r').readline().strip().split(',')] data = data.astype(np.dtype( [(n, 'float64') for n in csv_names] )) 

Los diagnósticos basados ​​en dimensiones coinciden con lo que espero:

 print len(csv_names) >> 108 print data.shape >> (1652, 108) 

“print data.dtype.names” también devuelve el resultado esperado.

Pero cuando empiezo a llamar columnas por sus nombres de campo, suceden cosas jodidas. La “columna” sigue siendo una matriz con 108 columnas …

 print data["EDUC"].shape >> (1652, 108) 

… y parece que contiene más valores perdidos que filas en el conjunto de datos.

 print np.sum(np.isnan(data["EDUC"])) >> 27976 

¿Alguna idea de lo que está pasando aquí? Agregar encabezados debería ser una operación trivial, pero he estado luchando contra este error durante horas. ¡Ayuda!

El problema es que estás pensando en términos de matrices similares a una hoja de cálculo, mientras que NumPy utiliza conceptos diferentes.

Esto es lo que debes saber sobre NumPy:

  1. Las matrices NumPy solo contienen elementos de un solo tipo .
  2. Si necesita “columnas” similares a una hoja de cálculo, este tipo debe ser un tipo similar a una tupla . Estas matrices se denominan matrices estructuradas, porque sus elementos son estructuras (es decir, tuplas).

En su caso, NumPy tomaría su matriz regular bidimensional y produciría una matriz unidimensional cuyo tipo es una tupla de 108 elementos (la matriz de hoja de cálculo en la que está pensando es bidimensional).

Estas elecciones probablemente se hicieron por razones de eficiencia: todos los elementos de un arreglo tienen el mismo tipo y, por lo tanto, tienen el mismo tamaño: se puede acceder a ellos, en un nivel bajo, de manera muy simple y rápida.

Ahora, como mostró user545424, hay una respuesta NumPy simple a lo que quiere hacer ( genfromtxt() acepta un argumento de names con nombres de columnas).

Si desea convertir su matriz de un ndarray NumPy normal a una matriz estructurada, puede hacer:

 data.view(dtype=[(n, 'float64') for n in csv_names]).reshape(len(data)) 

( astype() cerca: astype() lugar de view() ).

También puede consultar las respuestas a bastantes preguntas de Stackoverflow, incluida la conversión de una matriz numpy 2D a una matriz estructurada y cómo convertir una matriz numpy normal a una matriz grabada. .

Desafortunadamente, no sé qué sucede cuando intenta agregar los nombres de los campos, pero sí sé que puede crear la matriz que desee directamente desde el archivo a través de

 data = np.genfromtxt(csv_file, delimiter=',', names=True) 

EDITAR:

Parece que agregar nombres de campo solo funciona cuando la entrada es una lista de tuplas:

 data = np.array(map(tuple,data), [(n, 'float64') for n in csv_names])