删除非常大的数据集上的重复项

Removing duplicates on very large datasets

我正在处理一个 13.9 GB 的 csv 文件,其中包含大约 1600 万行和 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。我的 ram 是 16gb,不能再高了。有没有一种更有效的删除重复项的方法,它可能会在我不必将 csv 文件分解成更小的文件的情况下分块?

最简单的解决方案是为文件中的每一行创建一个散列 table - 在您的工作内存中存储 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 + set 开销,但这仍然远远少于将所有内容存储在内存中 - 对于 16M 行的 CSV 文件,您预计需要约 500MB 的内存使用。

UNIX 模拟器怎么样?

uniq <filename> >outputfile.txt

(类似的东西)

基本相同,但检查具有相同散列的行是否相等(而不是自动丢弃重复的散列)。

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