web-dev-qa-db-fra.com

Suppression des doublons sur de très grands ensembles de données

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?

8
Vlad

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))
1
jdehesa

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.

5
zwer

Qu'en est-il d'un simulateur UNIX?

uniq <filename> >outputfile.txt

(quelque chose comme ca)

0
Dominique