Je travaille sur un fichier csv de 13,9 Go contenant environ 16 millions de lignes et 85 colonnes. Je sais que quelques centaines de milliers de lignes peuvent être dupliquées. J'ai couru ce code pour les supprimer
import pandas
concatDf=pandas.read_csv("C:\\OUT\\Concat EPC3.csv")
nodupl=concatDf.drop_duplicates()
nodupl.to_csv("C:\\OUT\\Concat EPC3- NoDupl.csv",index=0)
low_memory=False
Cependant, cela me met dans une MemoryError. Mon bélier est 16gb et ne peut pas aller plus haut. Existe-t-il un moyen plus efficace de supprimer les doublons, ce qui permet de réduire en morceaux sans que je doive diviser le fichier CSV en fichiers plus petits?
Essentiellement la même idée que zwer , mais en vérifiant l’égalité des lignes avec le même hachage (au lieu de supprimer automatiquement les hachages dupliqués).
file_in = "C:\\OUT\\Concat EPC3.csv"
file_out = "C:\\OUT\\Concat EPC3- NoDupl.csv"
with open(file_in, 'r') as f_in, open(file_out, 'w') as f_out:
# Skip header
next(f_in)
# Find duplicated hashes
hashes = set()
hashes_dup = {}
for row in f_in:
h = hash(row)
if h in hashes:
hashes_dup[h] = set()
else:
hashes.add(h)
del hashes
# Rewind file
f_in.seek(0)
# Copy header
f_out.write(next(f_in))
# Copy non repeated lines
for row in f_in:
h = hash(row)
if h in hashes_dup:
dups = hashes_dup[h]
if row in dups:
continue
dups.add(row)
f_out.write(next(f_in))
La solution la plus simple serait de créer une table de hachage pour chaque ligne du fichier - le stockage de 16 millions de hachages dans votre mémoire de travail ne devrait pas poser de problème (cela dépend de la taille du hachage). Vous pouvez ensuite parcourir à nouveau votre fichier et vous assurer que vous écrivez une seule occurrence de chaque hachage. Vous n'avez même pas besoin d'analyser votre CSV ni de Pandas.
import hashlib
with open("input.csv", "r") as f_in, \
open("output.csv", "w") as f_out:
seen = set() # a set to hold our 'visited' lines
for line in f_in: # iterate over the input file line by line
line_hash = hashlib.md5(line.encode()).digest() # hash the value
if line_hash not in seen: # we're seeing this line for the first time
seen.add(line_hash) # add it to the hash table
f_out.write(line) # write the line to the output
Cela utilise MD5 comme hachage, donc il faudrait environ 16 milliards de ressources supplémentaires par ligne, mais cela reste bien moins que de tout stocker dans la mémoire - vous pouvez vous attendre à environ 500 Mo d’utilisation de la mémoire pour un fichier CSV de 16 millions de lignes.
Qu'en est-il d'un simulateur UNIX?
uniq <filename> >outputfile.txt
(quelque chose comme ca)