2017-02-25 20 views
0

私は巨大なテキストファイル(12GB)を持っています。行はタブで区切られ、最初の列にはIDが入ります。 IDごとに何かしたい。したがって、私の計画は最初の行から始め、次のIDに達するまで行ごとに最初の列を通ります。Python - テキストファイルの特定の行を読み込むには?

start_line = b 
num_lines = 377763316 

while b < num_lines: 
    plasmid1 = linecache.getline("Result.txt", b-1) 
    plasmid1 = plasmid1.strip("\n") 
    plasmid1 = plasmid1.split("\t") 

    plasmid2 = linecache.getline("Result.txt", b) 
    plasmid2 = plasmid2.strip("\n") 
    plasmid2 = plasmid2.split("\t") 


    if not str(plasmid1[0]) == str(plasmid2[0]): 
     end_line = b 
     #do something 

コードは機能しますが、問題はラインキャッシングが毎回txtファイルをリロードするように見えるということです。パフォーマンスを向上させないと、コードは数年間実行されます。

問題の解決方法や代替方法を知っているとよいと思います。

おかげで、 フィリップ

+0

行はタブで区切られますか?私のコラムのように聞こえる? – RuDevel

+0

すべてのコードを表示してください。 'linecache'とは何ですか? – eguaio

+0

@eguaio:https://docs.python.org/3/library/linecache.html – cdarke

答えて

0

あなたは一度だけファイルを開き、行を反復処理する必要があります。

with open('Result.txt', 'r') as f: 
    aline = f.next() 
    currentid = aline.split('\t', 1)[0] 
    for nextline in f: 
     nextid = nextline.split('\t', 1)[0] 
     if nextid != currentid: 
      #do stuff 
      currentid = nextid 

単純なPythonを使用してください。 各繰り返しで1行だけが読み込まれます。分割内の追加の1引数は、最初のタブにのみ分割され、パフォーマンスが向上します。特別なライブラリではパフォーマンスは向上しません。プレーンなC言語の実装だけがこのアプローチを打ち負かすことができます。

AttributeError: '_io.TextIOWrapper' object hasを入手した場合は、Python 3.Xを使用している可能性があります(質問io-textiowrapper-objectを参照)。代わりにこのバージョンを試してください:

with open('Result.txt', 'r') as f: 
    aline = f.readline() 
    currentid = aline.split('\t', 1)[0] 
    while aline != '': 
     aline = f.readline() 
     nextid = aline.split('\t', 1)[0] 
     if nextid != currentid: 
      #do stuff 
      currentid = nextid 
+0

コメントありがとうございます! 次のエラーが表示されます。AttributeError: '_io.TextIOWrapper'オブジェクトに 'next'属性がありません アイデアはありますか? – Philipp

+0

これはpython 2と3の互換性がありませんでした。 – eguaio

0

私はnumpy.loadtxt()が行く方法だと思います。また、ファイルから実際に必要な列を指定するには、usecols引数を渡すと良いでしょう。 Numpyパッケージは、高いパフォーマンスを念頭に置いて書かれた頑丈なライブラリです。

loadtxt()を呼び出した後、ndarrayが返されます。

0

あなたはitertoolsを使用することができる:外側のループで

from itertools import takewhile 

class EqualityChecker(object): 
    def __init__(self, id): 
     self.id = id 

    def __call__(self, current_line): 
     result = False 
     current_id = current_line.split('\t')[0] 

     if self.id == current_id: 
      result = True 

     return result 


with open('hugefile.txt', 'r') as f: 
    for id in ids: 
     checker = EqualityChecker(id) 
     for line in takewhile(checker, f.xreadlines()): 
      do_stuff(line) 

idは実際ID非マッチング前の値を持つ最初の行から得ることができます。

関連する問題