Vider un tableau NumPy dans un fichier csv

545

Existe-t-il un moyen de vider un tableau NumPy dans un fichier CSV? J'ai un tableau NumPy 2D et dois le vider dans un format lisible par l'homme.

Dexter
la source

Réponses:

867

numpy.savetxt enregistre un tableau dans un fichier texte.

import numpy
a = numpy.asarray([ [1,2,3], [4,5,6], [7,8,9] ])
numpy.savetxt("foo.csv", a, delimiter=",")
Jim Brissom
la source
2
est-ce préférable à une boucle dans le tableau par dimension? Je suppose que oui.
Ehtesh Choudhury
51
vous pouvez également modifier le format de chaque figure avec le mot clé fmt. la valeur par défaut est '% .18e', cela peut être difficile à lire, vous pouvez utiliser '% .3e' donc seules 3 décimales sont affichées.
Andrea Zonca
3
Andrea, oui j'ai utilisé% 10.5f. C'était assez pratique.
Dexter
12
Votre méthode fonctionne bien pour les données numériques, mais elle renvoie une erreur pour les numpy.arraychaînes. Pourriez-vous prescrire une méthode pour enregistrer au format csv pour un numpy.arrayobjet contenant des chaînes?
Ébe Isaac
16
@ ÉbeIsaac Vous pouvez également spécifier le format sous forme de chaîne:fmt='%s'
Luis
137

Vous pouvez utiliser pandas. Cela prend de la mémoire supplémentaire, donc ce n'est pas toujours possible, mais c'est très rapide et facile à utiliser.

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

si vous ne voulez pas d'en-tête ou d'index, utilisez to_csv("/path/to/file.csv", header=None, index=None)

maxbellec
la source
4
Cependant, cela écrira également un index de colonne dans la première ligne.
RM-
5
@ RM- vous pouvez utiliserdf.to_csv("file_path.csv", header=None)
maxbellec
4
Pas bon. Cela crée un df et consomme de la mémoire supplémentaire pour rien
Tex
20
fonctionnait comme un charme, c'est très rapide - compromis pour une utilisation supplémentaire de la mémoire. les paramètres header=None, index=Nonesuppriment la ligne d'en-tête et la colonne d'index.
thepunitsingh
3
@DaveC: Vous devez définir l' commentsargument de mot clé sur '', le #sera supprimé.
Milind R
46

tofile est une fonction pratique pour ce faire:

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 page de manuel contient quelques notes utiles:

Il s'agit d'une fonction pratique pour le stockage rapide des données de la baie. Les informations sur l'endianité et la précision étant perdues, cette méthode n'est pas un bon choix pour les fichiers destinés à archiver des données ou à transporter des données entre des machines avec une endianité différente. Certains de ces problèmes peuvent être résolus en sortant les données sous forme de fichiers texte, au détriment de la vitesse et de la taille du fichier.

Remarque. Cette fonction ne produit pas de fichiers csv multi-lignes, elle enregistre tout sur une seule ligne.

atomh33ls
la source
5
Pour autant que je sache, cela ne produit pas de fichier csv, mais met tout sur une seule ligne.
Peter
@Peter, bon point, merci, j'ai mis à jour la réponse. Pour moi, il enregistre bien au format csv (bien que limité à une ligne). De plus, il est clair que l'intention du demandeur est de "le vider dans un format lisible par l'homme" - donc je pense que la réponse est pertinente et utile.
atomh33ls
6
Depuis la version 1.5.0, np.tofile () prend un paramètre optionnel newline = '\ n' pour autoriser la sortie multiligne. docs.scipy.org/doc/numpy-1.13.0/reference/generated/…
Kevin J. Black
2
En fait, np.savetext () fournit l'argument newline, pas np.tofile ()
eaydin
14

L'écriture de tableaux d'enregistrements sous forme de fichiers CSV avec en-têtes nécessite un peu plus de travail.

Cet exemple lit un fichier CSV avec l'en-tête sur la première ligne, puis écrit le même fichier.

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

Notez que cet exemple ne prend pas en compte les chaînes avec des virgules. Pour prendre en compte les devis pour les données non numériques, utilisez le csvpackage:

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
la source
C'est là que les pandas aident à nouveau. Vous pouvez faire: pd.DataFrame (out, columns = ['col1', 'col2']), etc
EFreak
10

Comme déjà discuté, la meilleure façon de vider le tableau dans un fichier CSV est d'utiliser la .savetxt(...)méthode. Cependant, il y a certaines choses que nous devons savoir pour le faire correctement.

Par exemple, si vous avez un tableau numpy avec dtype = np.int32as

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

et souhaitez enregistrer en utilisant en savetxttant que

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

Il stockera les données au format exponentiel à virgule flottante comme

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

Vous devrez modifier la mise en forme en utilisant un paramètre appelé fmtas

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

pour stocker les données dans leur format d'origine

Enregistrement des données au format gz compressé

En outre, savetxtpeut être utilisé pour stocker des données en .gzformat compressé qui pourraient être utiles lors du transfert des données sur le réseau.

Nous avons juste besoin de changer l'extension du fichier .gzet numpy s'occupera de tout automatiquement

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

J'espère que cela aide

Daksh
la source
1
Le fmt="%d"était ce que je cherchais. Je vous remercie!
payne
6

Je pense que vous pouvez également accomplir cela tout simplement comme suit:

  1. Convertir le tableau Numpy en une trame de données Pandas
  2. Enregistrer au format CSV

par exemple # 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

par exemple # 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
la source
5

si vous voulez écrire dans la colonne:

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

Ici, «a» est le nom du tableau numpy et «fichier» est la variable à écrire dans un fichier.

Si vous voulez écrire en ligne:

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

Si vous souhaitez enregistrer votre tableau numpy (par exemple your_array = np.array([[1,2],[3,4]])) dans une cellule, vous pouvez d'abord le convertir avec your_array.tolist().

Ensuite, enregistrez-le de manière normale dans une cellule, avec delimiter=';' et la cellule dans le fichier csv ressemblera à ceci[[1, 2], [2, 4]]

Ensuite, vous pouvez restaurer votre tableau comme ceci: your_array = np.array(ast.literal_eval(cell_string))

Mr Poin
la source
Eh bien, cela va littéralement détruire toutes les économies de mémoire pour l'utilisation d'un tableau
numpy
2

Vous pouvez également le faire avec du python pur sans utiliser de modules.

# 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
la source
1
Cela utilise beaucoup de mémoire . Préférez une boucle sur chaque ligne et formatez-la.
remram
@remram, cela dépend de vos données, mais oui, s'il est volumineux, il peut utiliser beaucoup de mémoire
Greg
2

En Python, nous utilisons le module csv.writer () pour écrire des données dans des fichiers csv. Ce module est similaire au module 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 délimiteur est une chaîne utilisée pour séparer les champs. La valeur par défaut est une virgule (,).

Tamil Selvan S
la source
Cela a déjà été suggéré: stackoverflow.com/a/41009026/8881141 Veuillez uniquement ajouter de nouvelles approches, ne répétez pas les suggestions publiées précédemment.
Monsieur T