2012-02-18 6 views
1

これは私の最初のスクリプトで、2つのゲノムファイルを比較しようとしています。正規表現でリスト要素を使って大文字で一致するものを探す

rs3094315  1  742429 AA 
rs12562034  1  758311 GG 
rs3934834  1  995669 CC 

各フィールド間のタブがあります。

ファイルの内容は次のようになります。各ファイルには約50万行あります。

これらを簡単に比較するために、両方のファイルに含まれているデータポイントのみを保持し、いずれかのデータポイントを破棄したいと考えました。これを行うために、私はユニークなすべてのDNA位置のリストを作成しましたが、元のデータファイルの各行を検索し、これらのユニークなDNA位置を含まないすべての行を新しいファイルに印刷しようとしています。

正規表現を使用してゲノムファイルを検索してすべての固有でないDNA位置を表示しようとするまで、コード内のすべてが機能しました。私の質問は2倍である

Traceback (most recent call last): 
    File "/Users/laurelhochstetler/scripts/identify_SNPs.py", line 57, in <module> 
    if re.match(item,"(.*)", Line): 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 137, in match 
    return _compile(pattern, flags).match(string) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 242, in _compile 
    p = sre_compile.compile(pattern, flags) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/sre_compile.py", line 500, in compile 
    p = sre_parse.parse(p, flags) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/sre_parse.py", line 673, in parse 
    p = _parse_sub(source, pattern, 0) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/sre_parse.py", line 308, in _parse_sub 
    itemsappend(_parse(source, state)) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/sre_parse.py", line 401, in _parse 
    if state.flags & SRE_FLAG_VERBOSE: 
TypeError: unsupported operand type(s) for &: 'str' and 'int' 

:私は、スクリプトがforループ内LaurelSNP_leftリスト内のすべての項目を印刷するために得ることができますが、私は、各項目のre.matchを使用しようとすると、私はこのエラーメッセージが表示されます

  1. 正規表現でリストを使用するにはどうすればよいですか?
  2. ここでやろうとしていることを達成するためのよりよい方法はありますか?ここで

私のコードです:

#!/usr/bin/env python 
import re #this imports regular expression module 
import collections 

MomGenome=open('/Users/laurelhochstetler/Documents/genetics fun/genome_Mary_Maloney_Full_20110514145353.txt', 'r') 
LaurelGenome=open('/Users/laurelhochstetler/Documents/genetics fun/genome_Laurel_Hochstetler_Full_20100411230740.txt', 'r') 
LineNumber = 0 
momSNP = [] 
LaurelSNP = [] 
f = open("mom_edit.txt","w") 
for Line in MomGenome: 
    if LineNumber > 0: 
     Line=Line.strip('\n') 
     ElementList=Line.split('\t') 

     momSNP.append(ElementList[0]) 

     LineNumber = LineNumber + 1 
MomGenome.close() 
for Line in LaurelGenome: 
    if LineNumber > 0: 
     Line=Line.strip('\n') 
     ElementList=Line.split('\t') 

     LaurelSNP.append(ElementList[0]) 

     LineNumber = LineNumber + 1 
momSNP_multiset = collections.Counter(momSNP)    
LaurelSNP_multiset = collections.Counter(LaurelSNP) 
overlap = list((momSNP_multiset and LaurelSNP_multiset).elements()) 
momSNP_left = list((momSNP_multiset - LaurelSNP_multiset).elements()) 
LaurelSNP_left = list((LaurelSNP_multiset - momSNP_multiset).elements()) 
LaurelGenome=open('/Users/laurelhochstetler/Documents/genetics fun/genome_Laurel_Hochstetler_Full_20100411230740.txt', 'r') 
i = 0 
for Line in LaurelGenome: 
    for item in LaurelSNP_left: 
      if i < 1961: 
       if re.match(item, Line): 
        pass 

       else: 
        print Line 

      i = i + 1 
    LineNumber = LineNumber + 1 
+0

入力ファイルの表示例を教えてください。 – Thomas

+0

23&meからの生データを使用している人を見て涼しいです! – Stedy

+0

さて、ファイルの行のいくつかの例を追加しました!そしてはい、Stedy、私は家系図の目的のために対立遺伝子のデータに夢中になります! – blizpix

答えて

0

あなたは、そのID発生していないファイル1ファイル1でのIDのセットを作成し、ファイル2をごループとしてそれらを使用し、ファイル2からすべての行を印刷したい:

momSNP = set() 
for line in MomGenome: 
    snp, rest = line.split(None, 1) # Split into two pieces only 
    momSNP.add(snp) 

for line in MyGenome: 
    snp, rest = line.split(None, 1) 
    if snp in momSNP: 
     print line 

この500kのSNPを保存するだけで済むので、メモリー上の問題はそれほど多くありません。

+0

これは最高でした。私のコードがいかに非効率的であるかはわかりませんでしたが、それは永遠に繰り返されていました。これはちょうど私がそれがほんの少しの時間内にしたいと思ったものでした、ありがとう! – blizpix

1

re.matchの3番目の引数はオプションです(マニュアルを参照してください)。

+0

さて、私は実際にそれを間違って入力した、私は元々持っていたものに修正しました:もしre.match(item、Line): – blizpix

+0

それでもエラーメッセージが表示されません。あなたの問題を解決しましたか? – alexis

+0

そうだね、それはもはやもう私にそのエラーを与えていません!すぐに実行し始めると、それは何度も繰り返し同じ行を出力するのでしかし、私は、私のネストされたループと間違って何かがあると信じています。 – blizpix

2

短い回答:私は、あなたがしようとしていることに対して正規表現が必要ないと思います。

長い回答:コードを分析してみましょう。それはwith文で改善することができることを

LineNumber = 0 
MomGenome = open('20110514145353.txt', 'r') 
for Line in MomGenome: 
    if LineNumber > 0: 
     Line = Line.strip('\n') 
     ElementList = Line.split('\t') 

     momSNP.append(ElementList[0]) 

     LineNumber = LineNumber + 1 

MomGenome.close() 

、と私はあなたのラインカウントはヘッダのいくつかの種類をスキップするだけであり、私はそのためのnext()を使用しますね:

冒頭にあります。

with open('20110514145353.txt') as mom_genome: 
    next(mom_genome) # skipping the first line 
    for line in mom_genome: 
     elements = line.strip().split('\t') 
     mom_SNP.append(elements[0]) 

あなたが気づいた場合、私はまた、変数のためのCamelCase名前、あなたには、いくつかのスタイルガイドを、次のことになります。この方法を使用しないようにしてみました。私も.strip('\n').strip()に変更しました。str.strip()をチェックして、それでもあなたが望むものがあるかどうか確認してください。
上記は他のファイルでも実行できます。

ファイルを読んだ後、この行があります:

overlap = list((momSNP_multiset and LaurelSNP_multiset).elements()) 

が、これは何をしたいんが、確かにいますか?
はそのandは次のように、&すべきではない:

overlap = list((momSNP_multiset & LaurelSNP_multiset).elements()) 

のは、この例を見てみましょう:

>>> from collections import Counter 
>>> a = Counter(a=4, b=2, c=0, d=-2) 
>>> b = Counter(a=2, b=0, c=0) 
>>> a 
Counter({'a': 4, 'b': 2, 'c': 0, 'd': -2}) 
>>> b 
Counter({'a': 2, 'c': 0, 'b': 0}) 
>>> a and b # This will return b 
Counter({'a': 2, 'c': 0, 'b': 0}) 
>>> c & d # this will return the common elements 
Counter({'a': 2}) 

a and bそれはbbool(a)以降はTrueにevaulatedされる戻ります、見てみましょうofficial doc

その後、それは試合になる、これは本当に明確ではない。あなたは:

私が最初に言ったように、あなたは正規表現を全く必要としないと思います。
そして私はあなたのような何かをしようとしていると思う:

with open('20100411230740.txt') as laural_genome: 
    for line in laureal_genome: 
     i = 0 
     for item in laurelSNP_left: 
      if i > 1960: 
       break 

      if line.strip().split('\t')[0] == item: 
       print line 

      i += 1 

私はこの答えの間に多くのことを推測するので、より多くの情報を与え、私は間違って推測場所を教えて気軽に:)

ましたが
+0

これはきれいだった。私は人々が投稿した他の提案をまだ試していないが、これは魅力的だった。私は本当にあなたはそれが本当の助けだ初心者として、私のためだけで物事を綴る感謝しています。どうもありがとうございます! – blizpix

0

問題について重大なものがありませんか?私は、この解決策が既存のものよりも驚くほど少ないと感じています。二つの異なるゲノムのファイルについては、私が持っている:最初のリードファイルのサイズよりも多くのスペースを必要としないながら

with file('zzz.txt') as f1: 
    first = frozenset([i.strip() for i in f1 if i.strip()]) 

with file('yyy.txt') as f2: 
    common = [i.strip().split('\t') for i in f2 if i.strip() in first] 

genomes = {} 
for i in common: 
    genomes[i[0]] = i[1:] 

これは、すべての重複(両方のファイルに共通するエントリを)出て印刷する必要があります。したがって、メモリの影響を最小限に抑えるために、小さいファイル(おそらくファイルサイズ)を事前にチェックすることで高速化できます。

正規表現はここでは必要ないように見えますが、この解法でない場合は、リスト内包表記を使用しないことをお奨めします。

EDIT:Python dictに各繰り返しを追加するように更新されました。

+0

例として、空の行が含まれているように見えるので、4つの.strip()呼び出しがありますが、これらのプロセスはコピー/ペーストのアーティファクトであれば削除できます。 – hexparrot

+0

タブで分割し、最初のフィールドのみでインデックスする必要があります.SNPに関する彼のコメントを参照してください。 – alexis

関連する問題