Pregunta numpy.genfromtxt produce un conjunto de tuplas que parecen matrices 2D, ¿por qué?


Estoy corriendo genfromtxt como abajo:

date_conv = lambda x: str(x).replace(":", "/")
time_conv = lambda x: str(x)

a = np.genfromtxt(input.txt, delimiter=',', skip_header=4,
      usecols=[0, 1] + radii_indices, converters={0: date_conv, 1: time_conv})

Dónde input.txt es desde esta esencia.

Cuando miro los resultados, es una matriz 1D y no una matriz 2D:

>>> np.shape(a)
(918,)

Parece ser una matriz de tuplas en su lugar:

>>> a[0]
('06/03/2006', '08:27:23', 6.4e-05, 0.000336, 0.001168, 0.002716, 0.004274, 0.004658, 0.003756, 0.002697, 0.002257, 0.002566, 0.003522, 0.004471, 0.00492, 0.005602, 0.006956, 0.008442, 0.008784, 0.006976, 0.003917, 0.001494, 0.000379, 6.4e-05)

Si elimino la especificación de convertidores del genfromtxt llamarlo funciona bien y produce una matriz 2D:

>>> np.shape(a)
(918, 24)

32
2018-03-02 13:51


origen


Respuestas:


Lo que se devuelve se llama ndarray estructurado, ver por ejemplo aquí: http://docs.scipy.org/doc/numpy/user/basics.rec.html. Esto se debe a que sus datos no son homogéneos, es decir, no todos los elementos tienen el mismo tipo: los datos contienen ambas cadenas (las dos primeras columnas) y flotantes. Las matrices numeradas deben ser homogéneas (ver aquí para una explicación).

Las matrices estructuradas "resuelven" esta restricción de homogeneidad mediante el uso de tuplas para cada registro o fila, esa es la razón por la que la matriz devuelta es 1D: una serie de tuplas, pero cada tupla (fila) consta de varios datos, por lo que puede considerarlo filas y columnas. Las diferentes columnas son accesibles como a['nameofcolumn'], en tu caso, por ej. a['Julian_Day'].

La razón por la que devuelve una matriz 2D al eliminar los convertidores de las dos primeras columnas es que ese es el caso, genfromtxt considera todos los datos del mismo tipo, y se devuelve un ndarray normal (el tipo predeterminado es flotante, pero puede especificarlo con el dtype argumento).

EDITAR: Si desea hacer uso de los nombres de las columnas, puede usar names argumento (y establecer el skip_header en solo tres):

a2 = np.genfromtxt("input.txt", delimiter=',', skip_header=3, names = True, dtype = None,
                  usecols=[0, 1] + radii_indices, converters={0: date_conv, 1: time_conv})

lo que puedes hacer, por ejemplo:

>>> a2['Dateddmmyyyy']
array(['06/03/2006', '06/03/2006', '18/03/2006', '19/03/2006',
       '19/03/2006', '19/03/2006', '19/03/2006', '19/03/2006',
       '19/03/2006', '19/03/2006'], 
      dtype='|S10')

43
2018-03-02 14:10