2017-02-15 9 views
2

私は*.txtファイルとして保存された(600,900,000,000)行列の形を持っています。行列の各行は、異なるサンプル名sample_name1,sample_name2などによって名前が付けられます。ただし、標準化されていないサンプル名があります。 s###30023Pythonで各行列行の文字を数えるには?カウンタ()?

その後、それぞれ約90億文字の3文字の文字列があります。

sample_name1 ab2ab222baab22ba2bab2b2aab22ab22bababab2baab2b2a

行列は、次の形式である:

600 9123001002 
sample_name1 ab2ab222baab22ba2bab2b2aab22ab22bababab2baab2b2a2bababab2baab2b2ab2a... 
sample_name2 abbbbbbbbbbbb2bbbbbbbbbbabbbbbbaaabbbbbbbbb222bbbbbabababbbb2b2b2bbb... 
... 

Iカウント固有の文字の数と各サンプルの辞書(またはリスト、パンダのデータフレーム)を作成したいです。すなわち、辞書形式:

sample_name1 = {'a': 1824600201, 'b': 2736900300, '2': 4561500501} 

各行についてです。

Pythonで文字を数える最も簡単な方法は、from collections import Counterです。テキストファイルをnumpyにロードし、行列の各行を繰り返し、各行にCounter()を使用します。

しかし、これらのラベルは標準化されていないため、1行ごとに正しいラベルをどのように削り取るのですか?おそらく、私は各行列の行の最初のX文字を取ることができますか?

+0

はありますあなたはスペースがテキストからラベルを分けることを保証しましたか? – AChampion

+0

@AChampionはい、タブのように見えます。 – ShanZhengYang

+0

@ ShanZhengYang:行内に他のスペース文字はありますか? –

答えて

1

(ラインあたり)メモリに合うようにデータの小さな十分な量を仮定すると、あなたはほど単純な何かができる:あなたの上にあなたの小さな例のデータセットを考えると

results = {} 
with open('<myfile>') as f: 
    next(f) # skip first line 
    for line in f: 
     title, code = line.strip().split(' ') 
     results[title] = Counter(code) 

が得る:

{'sample_name1': Counter({'.': 3, '2': 21, 'a': 22, 'b': 25}), 
'sample_name2': Counter({'.': 3, '2': 7, 'a': 8, 'b': 53})} 
+0

大文字のファイルを読み込んでいる方法がわからないのは分かりません(これはpython2.xです。これは他のSO読者には分かります) – ShanZhengYang

+0

固定で、文字列をファイルインターフェイスに変換するために 'stringIO(str)'を使用しました。ファイルは 'open( '')に置き換えられました。なぜこれがpython 2.xだと思いますか?私のデフォルト環境は3.xですか? – AChampion

+0

Python3.xに 'StringIO()'が存在しないと思いました – ShanZhengYang

1

これはデータとほぼ同じ大きさのものでテストしていませんが、次のようなものを試すことができます。

前提として、各行をチャンクで読み込み、アスキー文字a, b, 2をintに変換して実行ヒストグラムを取得します。チャンクで各行を読み取る理由は、各行が90億バイトであるためです。つまり、ファイルが多くのコンピュータのメモリに収まらないためです。

まずは何かを定義しましょう。 transtableは、a,b,2の文字を取り、0,1,2に変換する配列です。私はこれをこのように書いて、より多くのキャラクターがいるなら一般化できるようにします。結果はsample_name: np.array([a_count, b_count, 2_count])の形式の辞書histsに保存されます。

import numpy as np 

transtable = np.arange(256, dtype=np.uint8) 
transtable[np.frombuffer('ab2')] = np.arange(3) 

chunksize = 436549 # 9123001002/2/3^5/43 
invchunksize = 43*2*3**5 

hists = {} 
bins = np.arange(4) # 3 + 1 
# convenience function to take string buffer to counts of a,b,2 (0,1,2) 
hist_func = lambda buff: np.histogram(transtable[np.frombuffer(buff, np.uint8)], 
             bins=bins)[0] 

今、私たちは、ファイルを開くと、ファイルオープンを持つヘッダ

with open(infile, 'r') as fin: 
    header_line = fin.readline() 
    rows, cols = map(int, header_line.split()) 

を解析し、それによって今ループしてみましょう、まず今で

while True: 
     # parse name 
     name = '' 
     nextchar = '' 
     while nextchar != ' ': #may need to replace with '\t' 
      nextchar = fin.read(1) 
      name += nextchar 

サンプル名を取得サンプル名があるので、実際のデータを解析しましょう:

 hist = np.zeros(3) 
     for _ in xrange(invchunksize): 
      dat = np.fromfile(fin, dtype=np.uint8, count=(chunksize)) 
      # stop reading if we didn't get chunksize bytes during last read 
      if data.size != chunksize: 
       break 

      hist += hist_func(dat) 

     hists[name] = hist 

     # read newline character and continue on to next line 
     fin.read(1) 
関連する問題