0

次のプログラムは、2つのファイル(txt、各10MB)で約22時間実行されています。各ファイルには約100K行があります。誰かが私のコードがどれほど非効率的で、おそらくより速い方法であるかを教えてもらえますか?入力dictは順序付けられており、順序を保持する必要があります。

import collections

def uniq(input):
  output = []
  for x in input:
    if x not in output:
      output.append(x)
  return output

Su = {}
with open ('Sucrose_rivacombined.txt') as f:
    for line in f:
        (key, val) = line.split('\t')
        Su[(key)] = val
    Su_OD = collections.OrderedDict(Su)

Su_keys = Su_OD.keys()
Et = {}

with open ('Ethanol_rivacombined.txt') as g:
    for line in g:
        (key, val) = line.split('\t')
        Et[(key)] = val
    Et_OD = collections.OrderedDict(Et)

Et_keys = Et_OD.keys()

merged_keys = Su_keys + Et_keys
merged_keys =  uniq(merged_keys)

d3=collections.OrderedDict()

output_doc = open("compare.txt","w+")

for chr_local in merged_keys:
    line_output = chr_local
    if (Et.has_key(chr_local)):
        line_output = line_output + "\t" + Et[chr_local]
    else:
        line_output = line_output + "\t" + "ND"
    if (Su.has_key(chr_local)):
        line_output = line_output + "\t" + Su[chr_local]
    else:
        line_output = line_output + "\t" + "ND"

    output_doc.write(line_output + "\n")

入力ファイルは次のとおりです。すべてのキーが両方のファイルに存在するわけではありません

Su:
chr1:3266359    80.64516129
chr1:3409983    100
chr1:3837894    75.70093458
chr1:3967565    100
chr1:3977957    100


Et:
chr1:3266359    95
chr1:3456683    78
chr1:3837894    54.93395855
chr1:3967565    100
chr1:3976722    23

出力を次のようにしたいと思います。

chr1:3266359    80.645    95
chr1:3456683    ND        78
4

3 に答える 3

3

uniq入力はハッシュ可能であるため、これに置き換えます。

def uniq(input):
  output = []
  s = set()
  for x in input:
    if x not in s:
      output.append(x)
      s.add(x)
  return output

O(n^2)これにより、ほぼプロセスがほぼに削減されO(n)ます。

于 2012-05-02T16:11:24.657 に答える
1

独自の機能は必要ありません。

次のような擬似コード:

  1. ファイル 2 を OrderedDict として読み取る
  2. プロセス ファイル 1 アイテムを書き出す (既に正しく注文されている)
  3. pop、出力行の最後の部分はファイル 2 からのデフォルトで
  4. ファイル1が消費された後、ファイル2からOrdered dictを処理します

また、リスト内包表記が大好きです...次のようにファイルを読むことができます:

OrderedDict(line.strip().split('\t') for line in open('Ethanol_rivacombined.txt'))

順序付けられた dict と 'Sucrose_rivacombined.txt' は 1 つだけであり、メモリに入れられることさえありません。超高速であるべき

完全なコードを編集します(出力行の形式がわからない)

from collections import OrderedDict

Et_OD = OrderedDict(line.strip().split('\t') for line in open('Ethanol_rivacombined.txt'))

with open("compare.txt","w+") as output_doc:
    for line in open('Sucrose_rivacombined.txt'):
        key,val = line.strip().split('\t')
        line_out = '\t'.join((key,val,Et_OD.pop(key,'ND')))
        output_doc.write(line_out+'\n')

    for key,val in Et_OD.items():
        line_out = '\t'.join((key,'ND',val))
        output_doc.write(line_out+'\n')
于 2012-05-02T16:43:24.537 に答える
0

あなたoutputはリストですが、入力は辞書です。それらのキーは一意であることが保証されていますが、組み合わせであるリストのすべてnot in outputの要素と比較する必要があります。(そのチェックのためにn ^ 2の比較を行っています。)not

おそらく、uniqを次のように完全に置き換えることができます。

Su_OD.update(Et_OD)

これは私のために働きます:

from collections import OrderedDict

one = OrderedDict()
two = OrderedDict()

one['hello'] = 'one'
one['world'] = 'one'

two['world'] = 'two'
two['cats'] = 'two'

one.update(two)

for k, v in one.iteritems():
    print k, v

出力:

    hello one
    world two
    cats two
于 2012-05-02T16:13:42.813 に答える