En utilisant numpy.genfromtxt pour lire un fichier csv avec des chaînes contenant des virgules
J'essaie de lire dans un fichier csv avec numpy.genfromtxt
mais certains des champs sont des chaînes qui contiennent 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 (obtenu 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. Y a-t-il un moyen de le faire avec numpy, ou Ai-je juste besoin de lire les données avec le module csv
, puis de le convertir en un tableau numpy?
4 réponses
Vous pouvez utiliser pandas (la bibliothèque par défaut pour travailler avec dataframes (données hétérogènes) dans scientific Python) pour cela. C'est read_csv
je peux gérer ça. De la docs:
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 virgules.
En dehors d'un puissant lecteur csv, je peux aussi fortement conseiller pour utiliser des pandas avec les données hétérogènes que vous avez (l'exemple de sortie dans 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 traite pas de 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
, note qu'il peut prendre des itérateurs au lieu de fichiers, par exemple 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 seulement les virgules appropriées avec des onglets.
Si vous utilisez un numpy vous voulez 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 associe la puissance de la norme csv
module et Numpy est recfromcsv
. Par exemple, le module csv
a un bon contrôle et une bonne personnalisation des dialectes, des guillemets, des caractères d'échappement, etc., vous pouvez les ajouter à l'exemple ci-dessous.
L'exemple de fonction genfromcsv_mod
ci-dessous se lit dans un fichier csv compliqué similaire à ce que Microsoft Excel voit, qui peut contenir des virgules dans les champs entre guillemets. En interne, la fonction a 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)