web-dev-qa-db-ja.com

非常に大きなデータセットの重複を削除する

私は約1600万行85列を含む13.9GBのcsvファイルに取り組んでいます。重複している行が数十万行ある可能性があることを私は知っています。私はそれらを削除するためにこのコードを実行しました

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ファイルをより小さなファイルに分割することなくチャンクしますか?

11
Vlad

基本的に 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))
1
jdehesa

最も簡単な解決策は、ファイルの各行にハッシュテーブルを作成することです-作業メモリに16Mのハッシュを保存することは問題ではないはずです(ハッシュサイズによって異なります)-その後、ファイルをもう一度繰り返して確認することができます各ハッシュのオカレンスを1つだけ書き留めること。 CSVを解析する必要も、パンダも必要ありません。

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を使用するため、1行あたり約16B +セットのオーバーヘッドが必要になりますが、それでもすべてをメモリに保存するよりもはるかに少なくなります。16M行のCSVファイルで最大500MBのメモリ使用量が期待できます。

5
zwer

UNIXシミュレーターはどうですか?

uniq <filename> >outputfile.txt

(そんな感じ)

0
Dominique