1

私は2つのファイルを持っています:

  1. metadata.csv: ID が含まれ、その後にベンダー名、ファイル名などが続きます。
  2. hashes.csv: ID が含まれ、その後にハッシュが続きます。ID は基本的に、ファイル メタデータをそのハッシュに関連付ける一種の外部キーです。

特定のベンダーに関連するすべてのハッシュをすばやく抽出するために、このスクリプトを作成しました。hashes.csv の処理が完了する前にクラップアウトします

stored_ids = []

# this file is about 1 MB
entries = csv.reader(open(options.entries, "rb"))

for row in entries:
  # row[2] is the vendor
  if row[2] == options.vendor:
    # row[0] is the ID
    stored_ids.append(row[0])

# this file is 1 GB
hashes = open(options.hashes, "rb")

# I iteratively read the file here,
# just in case the csv module doesn't do this.
for line in hashes:

  # not sure if stored_ids contains strings or ints here...
  # this probably isn't the problem though
  if line.split(",")[0] in stored_ids:

    # if its one of the IDs we're looking for, print the file and hash to STDOUT
    print "%s,%s" % (line.split(",")[2], line.split(",")[4])

hashes.close()

このスクリプトは、停止する前に hashes.csv から約 2000 のエントリを取得します。私は何を間違っていますか?行ごとに処理していると思いました。

ps。csv ファイルは一般的な HashKeeper 形式で、解析しているファイルは NSRL ハッシュ セットです。http://www.nsrl.nist.gov/Downloads.htm#converter

更新:以下の実用的なソリューション。コメントしてくれたみんなありがとう!

entries = csv.reader(open(options.entries, "rb"))   
stored_ids = dict((row[0],1) for row in entries if row[2] == options.vendor)

hashes = csv.reader(open(options.hashes, "rb"))
matches = dict((row[2], row[4]) for row in hashes if row[0] in stored_ids)

for k, v in matches.iteritems():
    print "%s,%s" % (k, v)
4

4 に答える 4

3

「クラップスアウト」は特に良い説明ではありません。それは何をするためのものか?スワップしますか?すべてのメモリをいっぱいにしますか? それとも、何もしていないように見えるだけで CPU を消費しますか?

ただし、最初は、リストではなく辞書を使用してstored_idsください。辞書での検索は通常 O(1) 時間で行われますが、リストでの検索は O(n) です。

編集:これは簡単なマイクロベンチマークです:

$ python -m timeit -s "l=range(1000000)" "1000001 in l"
10 loops, best of 3: 71.1 msec per loop
$ python -m timeit -s "s=set(range(1000000))" "1000001 in s"
10000000 loops, best of 3: 0.174 usec per loop

ご覧のとおり、セット (dict と同じパフォーマンス特性を持つ) は、同様のリストよりも 10000 倍以上高速に 100 万個の整数を検索します (検索あたり 1 マイクロ秒よりもはるかに短いのに対し、1 回の検索でほぼ 100 ミリ秒)。このようなルックアップが 1 GB ファイルの各行に対して行われることを考慮してください。問題がどれほど大きいかを理解できます。

于 2010-01-06T01:50:12.540 に答える
0

このコードは、コンマが 4 つ以上ない行で停止します。たとえば、空の行で終了します。csvリーダーを使用したくないことが確実な場合は、少なくともキャッチIndexErrorしてくださいline.split(',')[4]

于 2010-01-06T02:45:08.800 に答える
0

停止の意味を教えてください。ハングまたは終了しますか?エラーのトレースバックはありますか?

a)「、」がない行では失敗します

>>> 'hmmm'.split(",")[2]
Traceback (most recent call last):
  File "<string>", line 1, in <string>
IndexError: list index out of range

b)なぜ行を複数回分割するのですか?代わりにこれを行ってください

tokens = line.split(",")

if len(tokens) >=5 and tokens[0] in stored_ids:
    print "%s,%s" % (tokens[2], tokens[4])

c)stored_idsのdictを作成するため、stored_idのtokens [0]が高速になります

d) 内部コードを try/exept でラップし、エラーがあるかどうかを確認します

e)コマンドラインまたはIDEのどこで実行していますか?

于 2010-01-06T04:16:50.550 に答える
0

配列内の検索には O(n) かかったので、代わりに dict を使用してください

stored_ids = dict((row[0],1) for row in entries if row[2] == options.vendor)

または使用セット

a=set(row[0] for row in entries if row[2] == options.vendor)
b=set(line.split(",")[0] for line in hashes)
c=a.intersection(b)

ではc、ハッシュとcsvの両方の文字列のみが見つかります

于 2010-01-06T04:46:59.163 に答える