Dump di un array NumPy in un file CSV


545

C'è un modo per scaricare un array NumPy in un file CSV? Ho un array NumPy 2D e devo scaricarlo in un formato leggibile dall'uomo.

Risposte:


867

numpy.savetxt salva un array in un file di testo.

import numpy
a = numpy.asarray([ [1,2,3], [4,5,6], [7,8,9] ])
numpy.savetxt("foo.csv", a, delimiter=",")

2
è preferibile eseguire il looping attraverso l'array per dimensione? Sto indovinando così.
Ehtesh Choudhury,

51
puoi anche cambiare il formato di ogni figura con la parola chiave fmt. il valore predefinito è '% .18e', questo può essere difficile da leggere, puoi usare '% .3e' quindi vengono mostrati solo 3 decimali.
Andrea Zonca,

3
Andrea, Sì, ho usato% 10.5f. È stato abbastanza conveniente.
Dexter,

12
Il metodo funziona bene per i dati numerici, ma genera un errore per le numpy.arraystringhe. Potresti prescrivere un metodo per salvare come CSV per un numpy.arrayoggetto contenente stringhe?
Ébe Isaac,

16
@ ÉbeIsaac Puoi anche specificare il formato come stringa:fmt='%s'
Luis

137

È possibile utilizzare pandas. Richiede memoria aggiuntiva, quindi non è sempre possibile, ma è molto veloce e facile da usare.

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

se non si desidera un'intestazione o un indice, utilizzare to_csv("/path/to/file.csv", header=None, index=None)


4
Tuttavia, questo scriverà anche un indice di colonna nella prima riga.
RM-

5
@ RM- puoi usaredf.to_csv("file_path.csv", header=None)
maxbellec il

4
Non bene. Questo crea un df e consuma memoria extra per niente
Tex

20
ha funzionato come un incantesimo, è molto veloce: un compromesso per l'utilizzo di memoria extra. i parametri header=None, index=Nonerimuovono la riga di intestazione e la colonna dell'indice.
thepunitsingh

3
@DaveC: devi impostare l' commentsargomento della parola chiave su '', il #sarà soppresso.
Milind R

46

tofile è una comoda funzione per fare questo:

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 pagina man contiene alcune note utili:

Questa è una comoda funzione per una rapida memorizzazione dei dati dell'array. Le informazioni su endianness e precisione vanno perse, quindi questo metodo non è una buona scelta per i file destinati ad archiviare dati o trasportare dati tra macchine con endianness diversi. Alcuni di questi problemi possono essere risolti emettendo i dati come file di testo, a scapito della velocità e delle dimensioni del file.

Nota. Questa funzione non produce file CSV multilinea, ma salva tutto su una riga.


5
Per quanto posso dire, questo non produce un file CSV, ma mette tutto su una sola riga.
Peter,

@Peter, buon punto, grazie, ho aggiornato la risposta. Per me salva ok in formato CSV (anche se limitato a una riga). Inoltre, è chiaro che l'intento del richiedente è di "scaricarlo in un formato leggibile dall'uomo", quindi penso che la risposta sia pertinente e utile.
Atomh33ls,

6
Dalla versione 1.5.0, np.tofile () accetta un parametro facoltativo newline = '\ n' per consentire l'output su più righe. docs.scipy.org/doc/numpy-1.13.0/reference/generated/…
Kevin J. Black

2
In realtà, np.savetext () fornisce l'argomento newline, non np.tofile ()
eaydin,

14

Scrivere array di record come file CSV con intestazioni richiede un po 'più di lavoro.

Questo esempio legge un file CSV con l'intestazione sulla prima riga, quindi scrive lo stesso file.

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', ',')

Si noti che questo esempio non considera le stringhe con virgole. Per considerare le virgolette per i dati non numerici, utilizzare il csvpacchetto:

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())

Questo è dove i panda aiutano di nuovo. Puoi fare: pd.DataFrame (out, colonne = ['col1', 'col2']), ecc.
EFreak

10

Come già discusso, il modo migliore per scaricare l'array in un file CSV è usando il .savetxt(...)metodo. Tuttavia, ci sono alcune cose che dovremmo sapere per farlo correttamente.

Ad esempio, se si dispone di una matrice numpy con dtype = np.int32as

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

e vuoi salvare usando savetxtcome

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

Memorizzerà i dati in formato esponenziale in virgola mobile come

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

Dovrai cambiare la formattazione usando un parametro chiamato fmtas

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

per memorizzare i dati nel suo formato originale

Salvataggio dei dati in formato compresso gz

Inoltre, savetxtpuò essere utilizzato per l'archiviazione di dati in .gzformato compresso che potrebbe essere utile durante il trasferimento di dati in rete.

Dobbiamo solo cambiare l'estensione del file poiché .gznumpy si occuperà automaticamente di tutto

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

Spero che sia d'aiuto


1
L' fmt="%d"era quello che stavo cercando. Grazie!
Payne,

6

Credo che tu possa anche realizzare questo semplicemente come segue:

  1. Converti l'array Numpy in un frame di dati Pandas
  2. Salva come CSV

ad es. # 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

ad es. # 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

5

se vuoi scrivere nella colonna:

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

Qui "a" è il nome dell'array numpy e "file" è la variabile da scrivere in un file.

Se vuoi scrivere in fila:

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

2

Se vuoi salvare l'array numpy (ad es. your_array = np.array([[1,2],[3,4]])) In una cella, puoi prima convertirlo con your_array.tolist().

Quindi salvalo nel modo normale in una cella, con delimiter=';' e la cella nel file CSV sarà simile a questa[[1, 2], [2, 4]]

Quindi è possibile ripristinare l'array in questo modo: your_array = np.array(ast.literal_eval(cell_string))


beh, questo distruggerà letteralmente tutti i risparmi di memoria per l'utilizzo di un array
intorpidito

2

Puoi anche farlo con Python puro senza usare alcun modulo.

# 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)

1
Questo utilizza molta memoria . Preferisci il looping su ogni riga e formattalo e scrivilo.
remram,

@remram dipende dai tuoi dati, ma sì se è grande può usare molta memoria
Greg

2

In Python usiamo il modulo csv.writer () per scrivere i dati in file CSV. Questo modulo è simile al modulo 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 delimitatore è una stringa utilizzata per separare i campi. Il valore predefinito è virgola (,).


Questo è già stato suggerito: stackoverflow.com/a/41009026/8881141 Aggiungi solo nuovi approcci, non ripetere i suggerimenti pubblicati in precedenza.
Mr. T
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.