Удаление дубликатов на очень больших наборах данных - PullRequest
0 голосов
/ 19 сентября 2018

Я работаю над CSV-файлом объемом 13,9 ГБ, который содержит около 16 миллионов строк и 85 столбцов.Я знаю, что потенциально есть несколько сотен тысяч строк, которые являются дубликатами.Я запустил этот код, чтобы удалить их

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  

Однако это приводит меня к MemoryError.Мой баран 16 ГБ и не может идти выше.Есть ли более эффективный способ удаления дубликатов, который, возможно, использует фрагменты без необходимости разбивать файл csv на более мелкие файлы?

Ответы [ 3 ]

0 голосов
/ 19 сентября 2018

А как насчет симулятора UNIX?

uniq <filename> >outputfile.txt

(что-то в этом роде)

0 голосов
/ 19 сентября 2018

По сути та же идея, что и zwer , но проверка на равенство в строках с одинаковым хешем (вместо автоматического удаления дублированных хешей).

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))
0 голосов
/ 19 сентября 2018

Самым простым решением было бы создание хеш-таблицы для каждой строки в файле - хранение 16M хешей в вашей рабочей памяти не должно быть проблемой (зависит от размера хеша, хотя) - тогда вы можете перебирать свой файл сноваи убедитесь, что вы записываете только одно вхождение каждого хэша.Вам даже не нужно анализировать CSV-файл и вам не нужны 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

Это использует MD5 в качестве хэша, поэтому потребуется около 16B + накладных расходов на каждую строку, но это все равно намного меньше, чем хранение всегов памяти - вы можете ожидать ~ 500 МБ использования памяти для файла CSV 16M строк.

...