2012-03-28 25 views
7

Quiero guardar una matriz 2D en un archivo CSV con información de "encabezado" de fila y columna (como una tabla). Sé que podría usar el argumento del encabezado para numpy.savetxt para guardar los nombres de las columnas, pero ¿hay alguna manera fácil de incluir también alguna otra matriz (o lista) como la primera columna de datos (como los títulos de las filas)?Python/Numpy - Guardar matriz con columna y títulos de fila

A continuación se muestra un ejemplo de cómo lo hago actualmente. ¿Hay una mejor manera de incluir esos títulos de fila, tal vez algún truco con savetxt que desconozco?

import csv 
import numpy as np 

data = np.arange(12).reshape(3,4) 
# Add a '' for the first column because the row titles go there... 
cols = ['', 'col1', 'col2', 'col3', 'col4'] 
rows = ['row1', 'row2', 'row3'] 

with open('test.csv', 'wb') as f: 
    writer = csv.writer(f) 
    writer.writerow(cols) 
    for row_title, data_row in zip(rows, data): 
     writer.writerow([row_title] + data_row.tolist()) 

Respuesta

6

Tal vez prefiere hacer algo como esto:

# Column of row titles 
rows = np.array(['row1', 'row2', 'row3'], dtype='|S20')[:, np.newaxis] 
with open('test.csv', 'w') as f: 
    np.savetxt(f, np.hstack((rows, data)), delimiter=', ', fmt='%s') 

Esto está implícitamente convirtiendo data a una matriz de cadenas, y tarda unos 200 ms por cada millón de artículos en mi ordenador.

El dtype '|S20' significa cadenas de veinte caracteres. Si es demasiado baja, sus números se consiguen picada:

>>> np.asarray([123], dtype='|S2') 
array(['12'], 
    dtype='|S2') 

Otra opción, que desde mi prueba limitada es más lento, pero le da mucho más control y no tiene el problema de cortar estaría utilizando np.char.mod, como

# Column of row titles 
rows = np.array(['row1', 'row2', 'row3'])[:, np.newaxis] 
str_data = np.char.mod("%10.6f", data) 
with open('test.csv', 'w') as f: 
    np.savetxt(f, np.hstack((rows, str_data)), delimiter=', ', fmt='%s') 
+0

El uso de hstack tiene que volver a crear la matriz en la memoria, ¿verdad? Entonces, si los datos son muy grandes, entonces debemos reasignar esa memoria nuevamente. Para mi aplicación específica, es poco probable que sea un problema real, pero solo un punto que vale la pena mencionar. Y probablemente no hay forma de evitar esto. Parece algo que savetxt debería implementar internamente, incluso si debe hacer una solución similar a la mía (pero en el código C subyacente). –

+0

Sí, tienes razón. Creo que tal vez toda esta sobrecarga podría evitarse con una matriz de registros, y usando el hecho de que fmt acepta una lista de operadores de formateo, como 'fmt = ['% s', '% f', ...]', pero No estoy familiarizado con ellos, así que esto es solo una suposición. – jorgeca

+0

Ya, también consideré una matriz de registros. Creo que tienes razón, que podría usarse ... pero esperaba evitarlos ... supongo que elegiré el que parezca el menor de los dos males. –

Cuestiones relacionadas