0
votes

Utilisation de la compréhension de la liste pour créer des sublistes

J'ai quelques fichiers .csv que je lis et appends chaque colonne à une liste différente.

.csv Exemple de fichier: h3>
lst_a = []
lst_b = []
with open(csv_file, 'r') as f_read:
    csv_reader = csv.reader(f_read, delimiter = ',')
    for row in csv_reader:
        lst_a.append(float(row[0]))
        lst_b.append(float(row[1]))

print(lst_a)  # [0, 2, 4]
print(lst_b)  # [1, 3, 5]


6 commentaires

Êtes-vous opposé à utiliser une bibliothèque comme Pandas?


Oui, c'est extrêmement lent. Jetez un coup d'œil ici .


Si vous lisez des millions de fichiers, il va juste être lent (surtout en python). Vous voudrez peut-être envisager votre conception, avez-vous besoin de ces deux listes massives, ou pouvez-vous traiter les données comme vous iThérent, etc.


@RaPhaël Il est intéressant de noter que suffisamment en fonction du TimeIt, Pandas le fait mieux que votre code actuel tant que le fichier CSV a suffisamment de lignes. Lorsque votre fichier CSV avait 3 lignes, votre code fonctionne beaucoup mieux, mais une fois que j'ai développé mon CSV à ~ 5k lignes, une simple mise en œuvre de Pandas était environ deux fois plus rapide. (selon le temps imparti


@Chris_rands J'ai besoin d'effectuer un certain calcul dans deux listes avec 500 lignes 5M fois. J'utilisais un seul fichier JSON, mais j'ai commencé à avoir des problèmes de mémoire. Ensuite, j'ai tout sauvegardé dans un fichier HDF5, il était super lent, alors je continuais à utiliser des fichiers individuels individuels de 5 m.


@Karanshishoo J'ai recherché d'autres repères de Pandas et ils sont plus rapides que pour les fichiers plus importants que les vôtres, dans mon cas se trouve beaucoup de petits fichiers (500 rangées max).


3 Réponses :


4
votes

Ce n'est pas une bonne pratique ou un joli code Python, mais: xxx

fonctionne. La raison pour laquelle cela n'est pas recommandé est que vous créez une liste de Aucun avec des effets secondaires et des compréhensions de liste ont été conçues pour avoir des fonctions simples avec la sortie et aucun effet secondaire dans la compréhension. Le code 'APPEND' n'est exécuté que par l'interprète Python tente d'évaluer la liste, même si la liste n'est pas nécessaire. C'est une situation de la boucle pour la création de la boucle! Mais bien sûr, le choix est à vous.

EDIT: L'utilisation de zip est belle et concise: xxx

mais n'est pas performant. C'est parce que zip ira déterrer sur les rangées du CSV N fois où n est le nombre de colonnes, alors que la compréhension de la boucle ou de la liste sans zip ne sera pas. Donc, si vous avez un CSV d'un million de lignes et 10 colonnes, cela vous ralentira beaucoup.


5 commentaires

THX, j'espérais éviter le append () . S'il n'y a pas d'autre moyen, je garderai le pour la boucle .


Comme suggéré, la seule façon de voir pour cela utilise zip . lst_a, lst_b = * [[[float (i) pour i in x] pour x dans zip (* csv_reader)]


Il y a un extra * dans votre code, sans qu'elle fonctionne bien, mais aucune amélioration de la performance lorsque vous comparez au pour la boucle peut-être que c'est à cause de zip () .


corrigé cela, merci. Oui, c'est la raison pour laquelle je n'ai pas suggéré Zip pour commencer, pour un fichier avec des millions de lignes, Zip doit lire toutes les rangées avant de créer la liste afin de pouvoir être plus lente que ma réponse initiale, qui s'appuie sur une itération sur la Lignes


Il s'agit de millions de fichiers avec ~ 500 lignes, en fait. J'ai accepté la réponse puisque cela fait ce qui a été demandé. Merci pour votre temps.



2
votes

Il suffit d'utiliser zip ! Il se contentera de tous les 1er éléments, tous les 2nd éléments ... xxx

* csv_reader - L'étoile est la liste des déballements = Nous passons des éléments de la liste sous forme de paramètres séparés comme paramètres distincts . Cela permet de traiter toutes les sous-listes comme listes d'entrée pour zip .

résultat de zip est un objet zip - un générateur qui donne une itéraitée Sur, donc je devais utiliser liste () pour imprimer le résultat.


0 commentaires

1
votes

Vous pouvez le faire avec ZIP et une seule passe à travers le lecteur:

lst_a,lst_b = map(list,zip(*(map(float,row) for row in csvReader)))


1 commentaires

Merci. Fonctionne bien, mais il est plus lent en raison de la carte + zip.