2016-06-14 8 views
2

私はそれに約16,000行のファイルがあります。 これらはすべて同じ形式です。それならばここでは簡単な例です:1行の文字列と次の行の文字列を比較する方法は?

ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 

<...> 

ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 

私は、文字列DPPCが含まれており、19に識別子切り替わる前に、50行ブロックを形成18識別子を持つ行あれば、今のところそうなど、

をチェックする必要があり、私は次のコードを持っています:

cnt = 0 
with open('test_file.pdb') as f1: 
    with open('out','a') as f2: 
     lines = f1.readlines() 
     for i, line in enumerate(lines): 
      if "DPPC" in line: 
        A = line.strip()[22:26] 
        if A[i] == A [i+1]: 
         cnt = cnt + 1 
        elif A[i] != A[i+1]: 
         cnt = 0 

ここで私は立ち往生しています。後続の行を比較する方法をいくつか見出しましたが、同様のアプローチはここでは機能しませんでした。 Aの値とAの値をline[i+1]の値で比較する方法はまだ分かりません。

+0

私はあなたの問題を正しく理解していますか? 5番目のフィールドに '18'という50行のブロックがあり、その後に '19'などのブロックが続くことを確認しますか? –

+0

'A'を' line.strip()[22:26] 'と定義します。' line'は 'i'番目の行です。 Sowhatは 'A [i + 1]'を意味しますか? –

+0

はい、exacltyです。この特定のケースでは、第5列に18,19などがいくつ含まれているかを知りたいと思います。 – Diana

答えて

2

これを試してください(コメントの説明)。

data = """ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00""" 

# The last code seen in the 5th column. 
code = None 

# The count of lines of the current code. 
count = 0 

for line in data.split("\n"): 
    # Get the 5th column. 
    c = line.split()[4] 

    # The code in the 5th column changed. 
    if c != code: 
     # If we aren't at the start of the file, print the count 
     # for the code that just ended. 
     if code: 
      print("{}: {}".format(code, count)) 

     # Rember the new code. 
     code = c 

    # Count the line 
    count = count + 1 

# Print the count for the last code. 
print("{}: {}".format(code, count)) 

出力:

18: 9 
19: 19 
+1

ありがとう!私はちょうど私のデータセットであなたのコードをテストして、それは完全に動作します。 – Diana

0

また、簡単に並列リストでこれを解決することができます。

data = [] 
with open('data.txt', 'r') as datafile: 
    for line in datafile: 
     line=line.strip() 
     if line: 
      data.append(line); 


keywordList = [] 
for line in data: 
    line = line.split() 
    if (line[4] not in keywordList): 
     keywordList.append(line[4]) 


counterList = [] 
for item in keywordList: 
    counter = 0 
    for line in data: 
     line = line.split() 
     if (line[4] == item): 
      counter+=1 
    counterList.append(counter) 


for i in range(len(keywordList)): 
    print("%s: %d"%(keywordList[i],counterList[i])); 

しかし、あなたは辞書に精通している場合、私はルッツの答えと一緒に行きましょう。

1

データが固定幅レコードの固定幅フィールドであるように見えるので、structモジュールを使用すると、各行を個々のフィールドに素早く分割できます。

各行のすべてのフィールドを解析すると、そのうちの1つだけを処理する必要がある場合は残念ですが、他の処理を行う必要がある場合に備えて、 structモジュールはどんな場合でも比較的高速になります。

のは、入力ファイルはデータの唯一の次の行から成って言ってみましょう:あなたがする必要があるのは、フィールドの値がそれの比較を可能にするために、前の行にあったものを覚えていている

ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 139 C1 DPPC 18  17.250 58.420 10.850 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 19  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 20  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 20  23.050 20.800 11.000 1.00 0.00 
ATOM 189 C1 DPPC 20  23.050 20.800 11.000 1.00 0.00 

現在のもの。処理を開始するには、最初の行を別々に読み込んで解析する必要があります。したがって、後続の行と比較する値はprevです。また、第5フィールドは、[4]によってインデックスされたフィールドで、最初は[0]で始まるためです。

import struct 

# negative widths represent ignored padding fields 
fieldwidths = 4, -4, 3, -2, 2, -2, 4, -3, 2, -6, 6, -2, 6, -2, 6, -2, 4, -2, 4 
fmtstring = ' '.join('{}{}'.format(abs(fw), 'x' if fw < 0 else 's') 
            for fw in fieldwidths) 
fieldstruct = struct.Struct(fmtstring) 
parse = fieldstruct.unpack_from # a function to split line up into fields 

with open('test_file.pdb') as f1: 
    prev = parse(next(f1))[4] # remember value of fifth field 
    cnt = 1 
    for line in f1: 
     curr = parse(line)[4] # get value of fifth field 
     if curr == prev: # same as last one? 
      cnt += 1 
     else: 
      print('{} occurred {} times'.format(prev, cnt)) 
      prev = curr 
      cnt = 1 
    print('{} occurred {} times'.format(prev, cnt)) # for last line 

出力:

18 occurred 9 times 
19 occurred 7 times 
20 occurred 3 times 
関連する問題