J'essaie actuellement de lire des données à partir de fichiers .csv en Python 2.7 avec jusqu'à 1 million de lignes et 200 colonnes (les fichiers vont de 100 Mo à 1,6 Go). Je peux le faire (très lentement) pour les fichiers de moins de 300 000 lignes, mais une fois que je dépasse, j'obtiens des erreurs de mémoire. Mon code ressemble à ceci:
def getdata(filename, criteria):
data=[]
for criterion in criteria:
data.append(getstuff(filename, criteron))
return data
def getstuff(filename, criterion):
import csv
data=[]
with open(filename, "rb") as csvfile:
datareader=csv.reader(csvfile)
for row in datareader:
if row[3]=="column header":
data.append(row)
elif len(data)<2 and row[3]!=criterion:
pass
elif row[3]==criterion:
data.append(row)
else:
return data
La raison de la clause else dans la fonction getstuff est que tous les éléments qui correspondent au critère seront listés ensemble dans le fichier csv, donc je quitte la boucle lorsque je les dépasse pour gagner du temps.
Mes questions sont:
Comment puis-je faire en sorte que cela fonctionne avec les gros fichiers?
Y a-t-il moyen de le rendre plus rapide?
Mon ordinateur dispose de 8 Go de RAM, exécute Windows 7 64 bits et le processeur est de 3,40 GHz (je ne sais pas quelles informations vous avez besoin).
la source
Réponses:
Vous lisez toutes les lignes dans une liste, puis vous traitez cette liste. Ne fais pas ça .
Traitez vos lignes au fur et à mesure que vous les produisez. Si vous devez d'abord filtrer les données, utilisez une fonction de générateur:
J'ai également simplifié votre test de filtre; la logique est la même mais plus concise.
Comme vous ne correspondez qu'à une seule séquence de lignes correspondant au critère, vous pouvez également utiliser:
Vous pouvez maintenant boucler
getstuff()
directement. Faites de même dansgetdata()
:Maintenant, bouclez directement
getdata()
dans votre code:Vous n'avez plus qu'une seule ligne en mémoire, au lieu de vos milliers de lignes par critère.
yield
fait d'une fonction une fonction de générateur , ce qui signifie qu'elle ne fonctionnera pas tant que vous ne commencerez pas à la boucler.la source
csv.DictReader
? Parce que mes tests sur un fichier .csv de 2,5 Go montrent que le fait d'essayer d'itérer ligne par ligne comme ceci lorsque vous l'utilisez au lieu decsv.reader
faire croître le processus Python jusqu'à l'utilisation totale de la mémoire de 2,5 Go.Bien que la réponse de Martijin soit probablement la meilleure. Voici une façon plus intuitive de traiter de gros fichiers csv pour les débutants. Cela vous permet de traiter des groupes de lignes ou de blocs à la fois.
la source
Je fais pas mal d'analyses vibratoires et je regarde de grands ensembles de données (dizaines et centaines de millions de points). Mes tests ont montré que la fonction pandas.read_csv () était 20 fois plus rapide que numpy.genfromtxt (). Et la fonction genfromtxt () est 3 fois plus rapide que la fonction numpy.loadtxt (). Il semble que vous ayez besoin de pandas pour les grands ensembles de données.
J'ai publié le code et les ensembles de données que j'ai utilisés dans ces tests sur un blog discutant MATLAB vs Python pour l'analyse des vibrations .
la source
ce qui a fonctionné pour moi était et est ultra-rapide
Une autre solution de travail est:
la source
df_train=df_train.compute()
ligne de votre première solution ne charge-t-elle pas l'ensemble de données en mémoire ... ce qu'il essaie de ne pas faire?Pour quelqu'un qui atterrit à cette question. L'utilisation de pandas avec ' chunksize ' et ' usecols ' m'a aidé à lire un énorme fichier zip plus rapidement que les autres options proposées.
la source
voici une autre solution pour Python3:
voici
datareader
une fonction générateur.la source
Si vous utilisez des pandas et que vous avez beaucoup de RAM (assez pour lire le fichier entier en mémoire), essayez d'utiliser
pd.read_csv
aveclow_memory=False
, par exemple:la source