Volcar una matriz NumPy en un archivo csv

545

¿Hay alguna manera de volcar una matriz NumPy en un archivo CSV? Tengo una matriz 2D NumPy y necesito volcarla en formato legible para humanos.

Diestro
fuente

Respuestas:

867

numpy.savetxt guarda una matriz en un archivo de texto.

import numpy
a = numpy.asarray([ [1,2,3], [4,5,6], [7,8,9] ])
numpy.savetxt("foo.csv", a, delimiter=",")
Jim Brissom
fuente
2
¿Se prefiere esto a recorrer la matriz por dimensión? Supongo que sí.
Ehtesh Choudhury
51
También puede cambiar el formato de cada figura con la palabra clave fmt. el valor predeterminado es '% .18e', esto puede ser difícil de leer, puede usar '% .3e', por lo que solo se muestran 3 decimales.
Andrea Zonca
3
Andrea, sí, usé% 10.5f. Fue muy conveniente.
Dexter
12
Su método funciona bien para datos numéricos, pero arroja un error numpy.arrayde cadenas. ¿Podría prescribir un método para guardar como csv para un numpy.arrayobjeto que contiene cadenas?
Ébe Isaac
16
@ ÉbeIsaac También puede especificar el formato como cadena:fmt='%s'
Luis
137

Puedes usar pandas. Requiere algo de memoria adicional, por lo que no siempre es posible, pero es muy rápido y fácil de usar.

import pandas as pd 
pd.DataFrame(np_array).to_csv("path/to/file.csv")

si no quieres un encabezado o índice, usa to_csv("/path/to/file.csv", header=None, index=None)

maxbellec
fuente
44
Sin embargo, esto también escribirá un índice de columna en la primera fila.
RM-
55
@ RM- puedes usardf.to_csv("file_path.csv", header=None)
maxbellec
44
No está bien. Esto crea un df y consume memoria extra para nada
Tex
20
funcionó a las mil maravillas, es muy rápido: compensación por el uso de memoria adicional. los parámetros header=None, index=Noneeliminan la fila del encabezado y la columna de índice.
thepunitsingh
3
@DaveC: debe establecer el commentsargumento de la palabra clave en '', #se suprimirá.
Milind R
46

tofile Es una función conveniente para hacer esto:

import numpy as np
a = np.asarray([ [1,2,3], [4,5,6], [7,8,9] ])
a.tofile('foo.csv',sep=',',format='%10.5f')

La página del manual tiene algunas notas útiles:

Esta es una función conveniente para el almacenamiento rápido de datos de matriz. Se pierde información sobre endianness y precisión, por lo que este método no es una buena opción para archivos destinados a archivar datos o transportar datos entre máquinas con diferente endianness. Algunos de estos problemas pueden superarse enviando los datos como archivos de texto, a expensas de la velocidad y el tamaño del archivo.

Nota. Esta función no produce archivos csv de varias líneas, guarda todo en una línea.

atomh33ls
fuente
55
Por lo que puedo decir, esto no produce un archivo csv, sino que pone todo en una sola línea.
Peter
@ Peter, buen punto, gracias, he actualizado la respuesta. Para mí, guarda bien en formato csv (aunque limitado a una línea). Además, está claro que la intención del autor de la pregunta es "volcarlo en formato legible para humanos", por lo que creo que la respuesta es relevante y útil.
atomh33ls
66
Desde la versión 1.5.0, np.tofile () toma un parámetro opcional newline = '\ n' para permitir la salida multilínea. docs.scipy.org/doc/numpy-1.13.0/reference/generated/…
Kevin J. Black
2
En realidad, np.savetext () proporciona el argumento de nueva línea, no np.tofile ()
eaydin
14

Escribir matrices de registros como archivos CSV con encabezados requiere un poco más de trabajo.

Este ejemplo lee un archivo CSV con el encabezado en la primera línea, luego escribe el mismo archivo.

import numpy as np

# Write an example CSV file with headers on first line
with open('example.csv', 'w') as fp:
    fp.write('''\
col1,col2,col3
1,100.1,string1
2,222.2,second string
''')

# Read it as a Numpy record array
ar = np.recfromcsv('example.csv')
print(repr(ar))
# rec.array([(1, 100.1, 'string1'), (2, 222.2, 'second string')], 
#           dtype=[('col1', '<i4'), ('col2', '<f8'), ('col3', 'S13')])

# Write as a CSV file with headers on first line
with open('out.csv', 'w') as fp:
    fp.write(','.join(ar.dtype.names) + '\n')
    np.savetxt(fp, ar, '%s', ',')

Tenga en cuenta que este ejemplo no considera cadenas con comas. Para considerar las comillas para datos no numéricos, use el csvpaquete:

import csv

with open('out2.csv', 'wb') as fp:
    writer = csv.writer(fp, quoting=csv.QUOTE_NONNUMERIC)
    writer.writerow(ar.dtype.names)
    writer.writerows(ar.tolist())
Mike T
fuente
Aquí es donde los pandas nuevamente ayudan. Puede hacer: pd.DataFrame (fuera, columnas = ['col1', 'col2']), etc.
EFreak
10

Como ya se discutió, la mejor manera de volcar la matriz en un archivo CSV es mediante el uso de .savetxt(...) método. Sin embargo, hay ciertas cosas que debemos saber para hacerlo correctamente.

Por ejemplo, si tiene una matriz con numpy dtype = np.int32como

   narr = np.array([[1,2],
                 [3,4],
                 [5,6]], dtype=np.int32)

y quiero guardar usando savetxtcomo

np.savetxt('values.csv', narr, delimiter=",")

Almacenará los datos en formato exponencial de coma flotante como

1.000000000000000000e+00,2.000000000000000000e+00
3.000000000000000000e+00,4.000000000000000000e+00
5.000000000000000000e+00,6.000000000000000000e+00

Tendrá que cambiar el formato utilizando un parámetro llamado fmtcomo

np.savetxt('values.csv', narr, fmt="%d", delimiter=",")

para almacenar datos en su formato original

Guardar datos en formato comprimido gz

Además, savetxtse puede usar para almacenar datos en.gz formato comprimido que pueden ser útiles al transferir datos a través de la red.

Solo necesitamos cambiar la extensión del archivo ya que .gznumpy se encargará de todo automáticamente

np.savetxt('values.gz', narr, fmt="%d", delimiter=",")

Espero eso ayude

Daksh
fuente
1
El fmt="%d"era lo que estaba buscando. ¡Gracias!
payne
6

Creo que también puedes lograr esto de la siguiente manera:

  1. Convierta la matriz de Numpy en un marco de datos de Pandas
  2. Guardar como CSV

ej. # 1:

    # Libraries to import
    import pandas as pd
    import nump as np

    #N x N numpy array (dimensions dont matter)
    corr_mat    #your numpy array
    my_df = pd.DataFrame(corr_mat)  #converting it to a pandas dataframe

ej. # 2:

    #save as csv 
    my_df.to_csv('foo.csv', index=False)   # "foo" is the name you want to give
                                           # to csv file. Make sure to add ".csv"
                                           # after whatever name like in the code
DrDEE
fuente
5

si quieres escribir en la columna:

    for x in np.nditer(a.T, order='C'): 
            file.write(str(x))
            file.write("\n")

Aquí 'a' es el nombre de la matriz numpy y 'archivo' es la variable para escribir en un archivo.

Si quieres escribir en fila:

    writer= csv.writer(file, delimiter=',')
    for x in np.nditer(a.T, order='C'): 
            row.append(str(x))
    writer.writerow(row)
Rimjhim
fuente
2

Si desea guardar su matriz numpy (por ejemplo your_array = np.array([[1,2],[3,4]])) en una celda, puede convertirla primero conyour_array.tolist() .

Luego guárdelo de la forma normal en una celda, con delimiter=';' y la celda en el archivo csv se verá así[[1, 2], [2, 4]]

Entonces podría restaurar su matriz de esta manera: your_array = np.array(ast.literal_eval(cell_string))

Señor poin
fuente
bueno, eso literalmente va a destruir todos los ahorros de memoria por usar una matriz
numpy
2

También puede hacerlo con Python puro sin usar ningún módulo.

# format as a block of csv text to do whatever you want
csv_rows = ["{},{}".format(i, j) for i, j in array]
csv_text = "\n".join(csv_rows)

# write it to a file
with open('file.csv', 'w') as f:
    f.write(csv_text)
Greg
fuente
1
Esto usa mucha memoria . Prefiere bucles sobre cada fila y formatea y escribe.
Remram
@remram depende de sus datos, pero sí, si es grande, puede usar mucha memoria
Greg
2

En Python usamos el módulo csv.writer () para escribir datos en archivos csv. Este módulo es similar al módulo csv.reader ().

import csv

person = [['SN', 'Person', 'DOB'],
['1', 'John', '18/1/1997'],
['2', 'Marie','19/2/1998'],
['3', 'Simon','20/3/1999'],
['4', 'Erik', '21/4/2000'],
['5', 'Ana', '22/5/2001']]

csv.register_dialect('myDialect',
delimiter = '|',
quoting=csv.QUOTE_NONE,
skipinitialspace=True)

with open('dob.csv', 'w') as f:
    writer = csv.writer(f, dialect='myDialect')
    for row in person:
       writer.writerow(row)

f.close()

Un delimitador es una cadena utilizada para separar campos. El valor predeterminado es coma (,).

Tamil Selvan S
fuente
Esto ya se ha sugerido: stackoverflow.com/a/41009026/8881141 Agregue solo nuevos enfoques, no repita las sugerencias publicadas anteriormente.
Sr. T