J'essaie de lire dans un fichier csv avec numpy.genfromtxt
mais certains champs sont des chaînes contenant des virgules. Les chaînes sont entre guillemets, mais numpy ne reconnaît pas les guillemets comme définissant une seule chaîne. Par exemple, avec les données dans 't.csv':
2012, "Louisville KY", 3.5
2011, "Lexington, KY", 4.0
le code
np.genfromtxt('t.csv', delimiter=',')
produit l'erreur:
ValueError: Certaines erreurs ont été détectées! Ligne # 2 (a 4 colonnes au lieu de 3)
La structure de données que je recherche est:
array([['2012', 'Louisville KY', '3.5'],
['2011', 'Lexington, KY', '4.0']],
dtype='|S13')
En regardant la documentation, je ne vois aucune option pour y faire face. Existe-t-il un moyen de le faire avec numpy, ou dois-je simplement lire les données avec le module csv
puis les convertir en un tableau numpy?
Vous pouvez utiliser pandas (la bibliothèque par défaut en devenir pour travailler avec des trames de données (données hétérogènes) en python scientifique) pour cela. C'est read_csv
peut gérer cela. De la documentation:
quotechar: chaîne
The character to used to denote the start and end of a quoted item. Quoted items can include the delimiter and it will be ignored.
La valeur par défaut est "
. Un exemple:
In [1]: import pandas as pd
In [2]: from StringIO import StringIO
In [3]: s="""year, city, value
...: 2012, "Louisville KY", 3.5
...: 2011, "Lexington, KY", 4.0"""
In [4]: pd.read_csv(StringIO(s), quotechar='"', skipinitialspace=True)
Out[4]:
year city value
0 2012 Louisville KY 3.5
1 2011 Lexington, KY 4.0
L'astuce ici est que vous devez également utiliser skipinitialspace=True
pour traiter les espaces après le délimiteur de virgule.
Mis à part un puissant lecteur csv, je peux également fortement conseiller d'utiliser pandas avec les données hétérogènes que vous avez (l'exemple de sortie en numpy que vous donnez sont toutes des chaînes, bien que vous puissiez utiliser des tableaux structurés).
Le problème avec la virgule supplémentaire, np.genfromtxt
Ne résout pas cela.
Une solution simple consiste à lire le fichier avec csv.reader()
du module csv de python dans une liste, puis à le vider dans un tableau numpy si vous le souhaitez.
Si vous voulez vraiment utiliser np.genfromtxt
, Notez qu'il peut prendre des itérateurs au lieu de fichiers, par ex. np.genfromtxt(my_iterator, ...)
. Ainsi, vous pouvez envelopper un csv.reader
Dans un itérateur et le donner à np.genfromtxt
.
Cela irait quelque chose comme ceci:
import csv
import numpy as np
np.genfromtxt(("\t".join(i) for i in csv.reader(open('myfile.csv'))), delimiter="\t")
Cela remplace essentiellement à la volée uniquement les virgules appropriées avec des tabulations.
Si vous utilisez un numpy, vous voudrez probablement travailler avec numpy.ndarray. Cela vous donnera un numpy.ndarray:
import pandas
data = pandas.read_csv('file.csv').as_matrix()
Les pandas géreront correctement le cas "Lexington, KY"
Faire une meilleure fonction qui combine la puissance du module standard csv
et recfromcsv
de Numpy. Par exemple, le module csv
a un bon contrôle et une bonne personnalisation des dialectes, des guillemets, des caractères d'échappement, etc., que vous pouvez ajouter à l'exemple ci-dessous.
L'exemple genfromcsv_mod
la fonction ci-dessous lit un fichier CSV compliqué similaire à ce que Microsoft Excel voit, qui peut contenir des virgules dans les champs entre guillemets. En interne, la fonction possède une fonction de générateur qui réécrit chaque ligne avec des délimiteurs de tabulation.
import csv
import numpy as np
def recfromcsv_mod(fname, **kwargs):
def rewrite_csv_as_tab(fname):
with open(fname, 'rb') as fp:
reader = csv.reader(fp)
for row in reader:
yield '\t'.join(row)
return np.recfromcsv(rewrite_csv_as_tab(fname), delimiter='\t', **kwargs)
# Use it to read a CSV file into a record array
x = recfromcsv_mod('t.csv', case_sensitive=True)