4

次のように、複数列 (13 列) のスペース区切りファイル (約 500 万行以上) があります。

 1. W5 403  407 P Y 2 2 PR 22  PNIYR 22222 12.753 13.247
 2. W5 404  408 N V 2 2 PR 22  PIYYR 22222 13.216 13.247
 3. W3 274  276 E G 1 1 EG 11  EPG 121 6.492 6.492
 4. W3 275  277 P R 2 1 PR 21  PGR 211 6.365 7.503
 5. W3 276  278 G Y 1 1 GY 11  GRY 111 5.479 5.479
 6. W3 46  49 G L 1 1 GY 11  GRY 111 5.176 5.176
 7. W4 47  50 D K 1 1 DK 11  DILK 1111 4.893 5.278
 8. W4 48  51 I K 1 1 IK 11  ILKK 1111 4.985 5.552

などなど、

これらの列のうちの 2 つ (列 8 と 11) に興味があり、特定のペア (列 8) の出現回数とそれに続く文字列 (列 11) をカウントしたいと考えています。

例、参照キー 'GY' : '111' の出現数: 2 キー 'PR' : '22222' の出現数: 2 キー 'DK' : '1111' の出現数 :1 キー 'EG' : '121' の出現回数: 1

私は辞書ベースの基本的な実装を持っています。

countshash={}
for l in bigtable:
          cont = l.split()
          if cont[7] not in countshash: countshash[cont[7]] = {}
          if cont[11] not in countshash[cont[7]]: countshash[cont[7]][cont[10]] = 0
          countshash[cont[7]][cont[10]]+= 1;

また、単純なawkベースのカウント(超高速)もありますが、Pythonでこれを行う効率的で高速な方法について疑問に思っていました. ご意見ありがとうございます。

4

4 に答える 4

4
from collections import Counter
Counter(tuple(row.split()[8:12:3]) for row in bigtable)

使用itemgetterはスライスよりも柔軟性があり、効率的かもしれません

from operator import itemgetter
ig = itemgetter(8, 11)
Counter(ig(row.split()) for row in bigtable)

使用imapすると、物事を少し速くすることもできます

from itertools import imap
Counter(imap(ig, imap(str.split, bigtable)))
于 2012-08-21T21:20:55.663 に答える
4

これが速度に役立つかどうかはわかりませんが、大量のdefaultdict-likeオブジェクトを作成しているので、もう少し読みやすくすることができると思います:

from collections import defaultdict

countshash = defaultdict(lambda: defaultdict(int))

for l in bigtable:
    cont = l.split()
    countshash[cont[7]][cont[10]] += 1
于 2012-08-21T21:02:00.250 に答える
1

さて、あなたはダブルルックアップを行っています。あなたはただ行うことができますcountshash[(cont[7],count[10])]+=1、これはより速いかもしれませんが、Pythonがそれをどのように実装するかに依存します。メモリフットプリントは少し大きくする必要があります。

次のような単純なもの:

countshash=defaultdict(int)
for l in bigtable:
          cont = l.split()
          countshash[(cont[7],cont[10])]+= 1;
于 2012-08-21T21:03:33.700 に答える
1
from collections import defaultdict

countshash = defaultdict(int)
for l in bigtable:
    cont = l.split()
    countshash[cont[7], cont[10]] += 1
于 2012-08-21T21:31:46.233 に答える