2つのcsvファイルがあります。最初の、input
は、さまざまなエラーのある入力番地で構成されています。2つ目ref
は、きれいな住所表です。内のレコードは、内のレコードinput
と一致する必要がありますref
。ファイルを一意のレコードを持つリストに変換するのは高速ですが、照合プロセスに到達すると、正規表現なしで内input
の2つのアドレスを照合するだけで85秒かかるため、非常に遅くなります。ref
の大きさを実感しますref
ここでの問題です。長さは100万レコードを超え、ファイルサイズは30MBです。この種のサイズではパフォーマンスの問題が発生することが予想されていましたが、2つのレコードだけにこれだけ長くかかることは許容できません(実際には、最大10,000レコード以上を一致させる必要がある場合があります。さらに、最終的には、ref
アイテムに正規表現を埋め込む必要があります。より柔軟なマッチングを可能にします。新しい正規表現モジュールのテストはさらに悪く、同じ2つのレコードに対してなんと185秒かかりinput
ます。大幅に高速化する最善の方法を知っている人はいますか?たとえば、郵便番号でインデックスを作成できますか?
次に、inputとrefからのサンプルアドレスをそれぞれ示します(前処理後)。
60651 N SPRINGFIELD AVE CHICAGO
60061 BROWNING CT VERNON HILLS
これが私がこれまでに持っているものです。(初心者なので、コードにはおそらくあらゆる種類の非効率性があることを認識していますが、それは問題ではありません):
import csv, re
f = csv.reader(open('/Users/benjaminbauman/Documents/inputsample.csv','rU'))
columns = zip(*f)
l = list(columns)
inputaddr = l[0][1:]
f = csv.reader(open('/Users/benjaminbauman/Documents/navstreets.csv','rU'))
f.next()
reffull = []
for row in f:
row = str(row[0:7]).strip(r'['']').replace("\'","")
if not ", , , , ," in row: reffull.append(row)
input = list(set(inputaddr))
ref1 = list(set(reffull))
ref2 = ref1
input_scrub = []
for i in inputaddr:
t = i.replace(',',' ')
input_scrub.append(' '.join(t.split()))
ref_scrub = []
for i in ref1:
t = i.replace(',',' ')
ref_scrub.append(' '.join(t.split()))
output_iter1 = dict([ (i, [ r for r in ref_scrub if re.match(r, i) ]) for i in input_scrub ])
unmatched_iter1 = [i for i, j in output_iter1.items() if len(j) < 1]
matched_iter1 = {i: str(j[0][1]).strip(r'['']') for i, j in output_iter1.items() if len(j) is 1}
tied_iter1 = {k: zip(*(v))[1] for k,v in output_iter1.iteritems() if len(v) > 1}