環境
CentOS
Python3
やりたいこと
メモリに乗りきらない大容量csvの重複レコード有無を判別したい。
補足
CentOS上で数十GBのcsvの集計を実施するタスクがある。
メモリに全レコード乗らないので、pandasでchunksizeを指定してTextFileReaderをループして集計する方針を立てた。
大部分の集計はこれで問題ないと思われたが、レコードを分割してしまうと全レコードに対して重複するレコードがないか確認する手段がないと気付いた。
概ね全カラム必要となるのでusecolでカラムを絞るのは不可。
csvの最大サイズが保証されないので、dtype明示してある程度メモリを節約してもオーバーフローする可能性あり。
試したこと
各カラムの値の組み合わせ毎に一意な識別子を生成する。
生成された識別子をリストに格納して重複判定する。
もしくはデリミタを設けて文字列型辺りでスタックして文字列検索して重複判定する。
例
A | B | C |
---|---|---|
1 | 2 | 3 |
4 | 5 | 6 |
7 | 8 | 9 |
上記テーブルの場合、
[123,456,789]に重複がないので重複レコードなし。
もしくは string型のstr = '/123/456/'と順番にスタックして、789が文字列内に含まれないので重複レコードなし。
以降は str = '/123/456/789/'として同様に後続の判定。
問題点
いずれの場合も数十GBのテーブルのすべてのレコードに対して識別子を生成する処理が必要となり、非常に処理時間が長くなってしまう。
かつ、レコードが非常に多い場合、リストでも文字列でもメモリに乗りきらない可能性がある。
結局知りたいこと
メモリは有限だが、csvの最大サイズは保証されない。
つまり、それらに依存せず、任意のメモリ内で分割して重複判定ができる方法があれば知りたい。
個人的には、少なくとも何らかの形でメモリに乗せきる必要はあると思う。
ただ、以前別件で鶴の一声があって、考えてみればそりゃそうだと思う様な手法で解決した実績があるので取り敢えず質問した次第です。
根幹的解決に至らずとも、少しでもメモリ効率を上げる手法がございましたらご提案いただけますと幸甚です。
回答3件