Le traitement parallèle d'un grand .fichier csv en Python
Je suis de traitement de gros fichiers CSV (de l'ordre de plusieurs go avec 10M de lignes) à l'aide d'un script Python.
Les fichiers ont différentes longueurs de ligne, et ne peut pas être chargé entièrement en mémoire pour l'analyse.
Chaque ligne est gérée séparément par une fonction dans mon script. Il faut environ 20 minutes pour analyser un fichier, et il semble que la vitesse d'accès disque n'est pas un problème, mais plutôt le traitement/les appels de fonction.
Le code ressemble à ceci (très simple). Le code utilise une structure de Classe, mais c'est similaire:
csvReader = csv.reader(open("file","r")
for row in csvReader:
handleRow(row, dataStructure)
Donné le calcul nécessite une structure de données partagées, quelle serait la meilleure manière d'exécuter l'analyse en parallèle en Python en utilisant plusieurs coeurs?
En général, comment puis-je lire plusieurs lignes à la fois à partir d'un .csv en Python pour le transfert dans un thread/processus? En boucle avec for
sur les rangées ne sonne pas très efficace.
Merci!
J'ai pensé à elle. C'est une question de dev contre la flexibilité. En ce moment j'insiste sur Python, parce que c'est tellement plus rapide de développer une analyse complexe du code.
Vous pouvez également utiliser la fh.readlines(taille) méthode de lire plusieurs MBs à la fois. Ensuite transmettre ces blocs de lignes dans un thread/processus.
OriginalL'auteur Ron | 2011-12-08
Vous devez vous connecter pour publier un commentaire.
Essayer d'analyse comparative de la lecture de votre fichier et l'analyse de chaque CSV ligne, mais ne rien faire avec elle. Vous exclu de l'accès au disque, mais vous avez encore besoin de voir si le CSV analyse est ce qui est lent ou si votre code est ce qu'il est lent.
Si c'est le CSV analyse qui est lent, vous pourriez être coincé, parce que je ne pense pas qu'il y a un moyen de sauter dans le milieu d'un fichier CSV sans balayage jusqu'à ce point.
Si c'est votre propre code, alors vous pouvez avoir un fil de la lecture du fichier CSV et l'abandon de lignes dans une file d'attente, et puis avoir plusieurs threads de traitement des lignes de cette file d'attente. Mais ne vous embêtez pas avec cette solution si le CSV analyse elle-même est ce qui est le rendre lent.
for
itération de boucle?Eh bien, trouvé ceci: stackoverflow.com/questions/2359253/... Il est assez proche de cette description, donc je suppose que je vais utiliser les files d'attente.
Je veux dire par exemple, exécutez la même pour la boucle, mais au lieu de
handleRow(row, dataStructure)
que vous venez de direpass
OriginalL'auteur
Ce qui pourrait être trop tard, mais juste pour les futurs utilisateurs, je vais poster quand même. Une autre affiche mentionné à l'aide de multitraitement. Je peux témoigner de il et peut aller dans le détail. Nous traitons avec des fichiers de plusieurs centaines de MO à plusieurs GO tous les jours à l'aide de Python. Donc, c'est certainement à la hauteur de la tâche. Certains des fichiers nous traitons ne sont pas des CSVs, de sorte que l'analyse peut être assez complexe et plus long que l'accès au disque. Cependant, la méthodologie est la même, peu importe quel type de fichier.
Vous pouvez traiter des pièces de gros fichiers en même temps. Voici le pseudo-code de la façon dont nous le faisons:
Comme je l'ai dit, c'est seulement le pseudo-code. Il devrait obtenir n'importe qui a commencé, qui a besoin de faire quelque chose de similaire. Je n'ai pas le code en face de moi, il suffit de le faire à partir de la mémoire.
Mais nous avons eu plus d'une vitesse 2x à partir de cette sur la première manche sans réglage fin. Vous pouvez régler le nombre de processus dans la piscine et la taille des morceaux pour obtenir encore plus accélérer en fonction de votre configuration. Si vous avez plusieurs fichiers, comme nous le faisons, de créer un pool de lire plusieurs fichiers en parallèle. Juste prendre garde à ne pas surcharger la zone avec un trop grand nombre de processus.
Remarque: Vous devez le mettre à l'intérieur un "principal" block pour s'assurer que l'infini les processus ne sont pas créés.
Absolument. C'était ce que notre code a l'aide de cette méthode. Nous ne faisions pas un simple diff comparaison, mais en correspondance des lignes dans les fichiers. Selon la taille du fichier, il peut être plus facile de lire toutes les lignes de chaque fichier et de parcourir les listes en même temps de faire la comparaison.
en fin de compte, j'ai lu tous mes fichiers dans la mémoire, et cela a bien fonctionné pour moi. les fichiers sont ~de 1 go chacun, mais le temps passé à traiter par ligne est significativement plus élevé que le coût du temps de lecture en mémoire par ligne.
OriginalL'auteur
En raison de la GIL, Python filetage de ne pas accélérer les calculs qui sont le processeur lié comme il peut avec IO lié.
Au lieu de cela, jetez un oeil à la module multiprocessing qui peut exécuter votre code sur plusieurs processeurs en parallèle.
OriginalL'auteur
Si les lignes sont complètement indépendantes juste diviser le fichier d'entrée en autant de fichiers que de Processeurs que vous avez. Après cela, vous pouvez exécuter autant d'instances de processus comme les fichiers d'entrée que vous avez maintenant. Ce cas, car ils sont complètement différents processus, ne sera pas lié par GIL problèmes.
OriginalL'auteur
Si vous utilisez zmq et un COURTIER intermédiaire, vous seriez en mesure de propagation de la ligne de traitement non seulement pour les Processeurs de votre ordinateur, mais à travers un réseau autant d'instances que nécessaire. Cela aurait pour effet de garantir que vous avez frappé un IO limite vs une limite de CPU 🙂
OriginalL'auteur
Viens de trouver une solution à ce problème. J'ai essayé
de la Piscine.imap
, et il semble que, pour simplifier le traitement de gros fichiers de manière significative.imap
a un avantage important quand vient le traitement de gros fichiers: Il renvoie des résultats dès qu'ils sont prêts, et non pas attendre que tous les résultats soient disponibles. Cela permet d'économiser beaucoup de mémoire.(Ici est non testé l'extrait de code qui lit un fichier csv ligne par ligne, chaque ligne et de l'écrire dans un autre fichier csv. Tout est fait en parallèle.)
OriginalL'auteur