Comment lire les données CSV dans un tableau d'enregistrements dans NumPy?

415

Je me demande s'il y a un moyen d'importer directement le contenu d'un fichier CSV dans un tableau enregistrement, beaucoup de la manière que de R read.table(), read.delim()et read.csv()importe des données de la famille à la trame de données de R?

Ou est-ce la meilleure façon d'utiliser csv.reader () puis d'appliquer quelque chose comme numpy.core.records.fromrecords()?

hatmatrix
la source

Réponses:

647

Pour ce faire, vous pouvez utiliser la genfromtxt()méthode de Numpy en définissant le delimiterkwarg sur une virgule.

from numpy import genfromtxt
my_data = genfromtxt('my_file.csv', delimiter=',')

Plus d'informations sur la fonction peuvent être trouvées dans sa documentation respective .

Andrew
la source
10
Et si vous voulez quelque chose de différents types? Vous aimez les cordes et les pouces?
CGTheLegend
11
@CGTheLegend np.genfromtxt ('monfichier.csv', delimiter = ',', dtype = None)
chickensoup le
2
numpy.loadtxt a très bien fonctionné pour moi aussi
Yibo Yang
11
J'ai essayé mais je n'obtiens que des nanvaleurs, pourquoi? Aussi avec loadtxt, je reçois UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 155: ordinal not in range(128). J'ai des trémas tels que ä et ö dans les données d'entrée.
hhh
1
@hhh essayez d'ajouter un encoding="utf8"argument. Python est l'un des rares logiciels modernes à provoquer fréquemment des problèmes d'encodage de texte, qui ressemblent à des choses du passé.
kolen
187

Je recommanderais la read_csvfonction de la pandasbibliothèque:

import pandas as pd
df=pd.read_csv('myfile.csv', sep=',',header=None)
df.values
array([[ 1. ,  2. ,  3. ],
       [ 4. ,  5.5,  6. ]])

Cela donne un pandas DataFrame - permettant de nombreuses fonctions de manipulation de données utiles qui ne sont pas directement disponibles avec les tableaux d'enregistrement numpy .

DataFrame est une structure de données étiquetée en 2 dimensions avec des colonnes de types potentiellement différents. Vous pouvez y penser comme une feuille de calcul ou un tableau SQL ...


Je recommanderais également genfromtxt. Cependant, puisque la question demande un tableau d'enregistrement , par opposition à un tableau normal, le dtype=Noneparamètre doit être ajouté à l' genfromtxtappel:

Compte tenu d' un fichier d'entrée, myfile.csv:

1.0, 2, 3
4, 5.5, 6

import numpy as np
np.genfromtxt('myfile.csv',delimiter=',')

donne un tableau:

array([[ 1. ,  2. ,  3. ],
       [ 4. ,  5.5,  6. ]])

et

np.genfromtxt('myfile.csv',delimiter=',',dtype=None)

donne un tableau d'enregistrement:

array([(1.0, 2.0, 3), (4.0, 5.5, 6)], 
      dtype=[('f0', '<f8'), ('f1', '<f8'), ('f2', '<i4')])

Cela a l'avantage que le fichier avec plusieurs types de données (y compris les chaînes) peut être facilement importé .

atomh33ls
la source
read_csv fonctionne avec des virgules entre guillemets. Recommander ceci sur genfromtxt
Viet
3
utilisez header = 0 pour ignorer la première ligne dans les valeurs, si votre fichier a un en-tête d'une ligne
c-chavez
Gardez à l'esprit que cela crée un tableau 2D: par exemple (1000, 1). np.genfromtxtne fait pas cela: par exemple (1000,).
Newskooler
74

J'ai chronométré le

from numpy import genfromtxt
genfromtxt(fname = dest_file, dtype = (<whatever options>))

contre

import csv
import numpy as np
with open(dest_file,'r') as dest_f:
    data_iter = csv.reader(dest_f,
                           delimiter = delimiter,
                           quotechar = '"')
    data = [data for data in data_iter]
data_array = np.asarray(data, dtype = <whatever options>)

sur 4,6 millions de lignes avec environ 70 colonnes et a constaté que le chemin NumPy a pris 2 min 16 secondes et la méthode de compréhension csv-list a pris 13 secondes.

Je recommanderais la méthode de compréhension csv-list car elle repose très probablement sur des bibliothèques précompilées et non pas sur l'interpréteur autant que NumPy. Je soupçonne que la méthode des pandas aurait des frais généraux d'interprète similaires.

William komp
la source
23
J'ai testé un code similaire à celui-ci avec un fichier csv contenant 2,6 millions de lignes et 8 colonnes. numpy.recfromcsv () a pris environ 45 secondes, np.asarray (list (csv.reader ())) a pris environ 7 secondes et pandas.read_csv () a pris environ 2 secondes (!). (Le fichier avait récemment été lu sur le disque dans tous les cas, il était donc déjà dans le cache de fichiers du système d'exploitation.) Je pense que je vais utiliser les pandas.
Matthias Fripp
5
Je viens de remarquer qu'il y a quelques notes sur la conception de l'analyseur csv rapide des pandas sur wesmckinney.com/blog/… . L'auteur prend très au sérieux les exigences de vitesse et de mémoire. Il est également possible d'utiliser as_recarray = True pour obtenir le résultat directement sous la forme d'un tableau d'enregistrement Python plutôt que d'une trame de données pandas.
Matthias Fripp du
67

Vous pouvez également essayer recfromcsv()qui peut deviner les types de données et retourner un tableau d'enregistrement correctement formaté.

btel
la source
9
Si vous souhaitez conserver les noms de classement / colonne dans le CSV, vous pouvez utiliser l'invocation suivante: numpy.recfromcsv(fname, delimiter=',', filling_values=numpy.nan, case_sensitive=True, deletechars='', replace_space=' ')Les arguments clés sont les trois derniers.
eacousineau du
16

Comme j'ai essayé les deux façons d'utiliser NumPy et Pandas, l'utilisation de pandas présente de nombreux avantages:

  • plus rapide
  • Moins d'utilisation du processeur
  • 1/3 d'utilisation de RAM par rapport à NumPy genfromtxt

Voici mon code de test:

$ for f in test_pandas.py test_numpy_csv.py ; do  /usr/bin/time python $f; done
2.94user 0.41system 0:03.05elapsed 109%CPU (0avgtext+0avgdata 502068maxresident)k
0inputs+24outputs (0major+107147minor)pagefaults 0swaps

23.29user 0.72system 0:23.72elapsed 101%CPU (0avgtext+0avgdata 1680888maxresident)k
0inputs+0outputs (0major+416145minor)pagefaults 0swaps

test_numpy_csv.py

from numpy import genfromtxt
train = genfromtxt('/home/hvn/me/notebook/train.csv', delimiter=',')

test_pandas.py

from pandas import read_csv
df = read_csv('/home/hvn/me/notebook/train.csv')

Fichier de données:

du -h ~/me/notebook/train.csv
 59M    /home/hvn/me/notebook/train.csv

Avec NumPy et pandas aux versions:

$ pip freeze | egrep -i 'pandas|numpy'
numpy==1.13.3
pandas==0.20.2
HVNSweeting
la source
5

Vous pouvez utiliser ce code pour envoyer des données de fichier CSV dans un tableau:

import numpy as np
csv = np.genfromtxt('test.csv', delimiter=",")
print(csv)
chamzz.dot
la source
4

En utilisant numpy.loadtxt

Une méthode assez simple. Mais cela nécessite que tous les éléments soient flottants (int et ainsi de suite)

import numpy as np 
data = np.loadtxt('c:\\1.csv',delimiter=',',skiprows=0)  
Xiaojian Chen
la source
4

C'est le moyen le plus simple:

import csv with open('testfile.csv', newline='') as csvfile: data = list(csv.reader(csvfile))

Maintenant, chaque entrée de données est un enregistrement, représenté sous forme de tableau. Vous avez donc un tableau 2D. Cela m'a fait gagner beaucoup de temps.

Matthew Park
la source
Pourquoi devrions-nous avoir à déconner avec Pandas, alors que ces outils ont tellement moins de ballonnement?
Christopher
3

J'ai essayé ceci:

import pandas as p
import numpy as n

closingValue = p.read_csv("<FILENAME>", usecols=[4], dtype=float)
print(closingValue)
muTheTechie
la source
3

Je suggère d'utiliser des tableaux ( pip3 install tables). Vous pouvez enregistrer votre .csvfichier en .h5utilisant pandas ( pip3 install pandas),

import pandas as pd
data = pd.read_csv("dataset.csv")
store = pd.HDFStore('dataset.h5')
store['mydata'] = data
store.close()

Vous pouvez ensuite facilement et avec moins de temps, même pour une énorme quantité de données, charger vos données dans un tableau NumPy .

import pandas as pd
store = pd.HDFStore('dataset.h5')
data = store['mydata']
store.close()

# Data in NumPy format
data = data.values
Jatin Mandav
la source
3

Ce travail comme un charme ...

import csv
with open("data.csv", 'r') as f:
    data = list(csv.reader(f, delimiter=";"))

import numpy as np
data = np.array(data, dtype=np.float)
Nihal Sargaiya
la source
le code doit être correctement mis en retrait dans sa disposition de démarque de code.
surajs1n