これが発生する理由は次のとおりです。
カスタム オブジェクトの一意のセットを作成するには、オブジェクトに少なくとも と を実装する必要があり__eq__
ます__hash__
。
デモ:
class Obj(object):
def __init__(self,val):
self.val=val
def __repr__(self):
return self.val
li=['i am uniq','i am uniq','i am uniq','not really','not really','not really']
print set(Obj(e) for e in li)
版画
set([i am uniq, i am uniq, not really, not really, i am uniq, not really])
__eq__
必要な__hash__
メソッドを追加します。
class Obj(object):
def __init__(self,val):
self.val=val
self.hash=hash(val)
def __repr__(self):
return self.val
def __eq__(self,other):
return self.hash==other.hash
def __hash__(self):
return self.hash
li=['i am uniq','i am uniq','i am uniq','really','really','really']
print set(Obj(e) for e in li)
版画:
set([i am uniq, really])
適切なハッシュと eq がないと、セットがまったくないことがわかります。Jobs
obj idに基づく順序付けられていないリストが作成されます。つまり、Python にとっては、「同じ」と定義したオブジェクトであっても、それぞれが異なる obj id を持っているため、異なるオブジェクトとして扱われます。この「セット」は、実際には同等のリストよりもかなり大きくなります。
それはさておき-これを行うためのよりメモリ効率の良い方法は、おそらくジェネレーターでnumpyの構造化配列を使用して、ファイルを行ごとに読み取ることです。
ストラテジー:
- ファイルを開く
- ファイルの合計行数を決定します。これは、ファイル内の最悪の場合の合計レコード数です。
- ファイルを巻き戻す
- 最初のレコードを読み取り、行データ (int、float、bytes など) のレコードに基づいて、numpy 配列の最も効率的なレコード構造を決定します。これは、Python オブジェクトの場合よりもはるかに高密度です。
- ファイルを巻き戻す
- データを一意化するためにハッシュが必要な場合は、それをレコードに追加します
- numpy配列を
lines X records
サイズに事前に割り当てます
- ファイルを 1 行ずつ読み取り、各レコードを numpy 配列に配置するジェネレータを作成します。
- 重複するレコードを追加しないでください (ハッシュに基づく)
- 追加されていない重複レコードの総数の numpy 配列のサイズを変更します...