3

実行しようとしているタスクを解決するために使用するデータ構造と関数について、本当にアドバイスが必要です。ここでの最善のアプローチがわかりません。

問題/タスク: 染色体の開始位置と終了位置のリストがあります。このデータをタプルのリスト(?)または同様のものにプッシュし、start_end範囲値を指定してこれらの座標を二分する最良の方法を見つけようとしています.以前は二分法を使用しましたが、単一の値エントリを含むリストに対してのみしたがって、多値比較にアプローチする最善の方法が何であるかはわかりません。

例えば、私が以下の遺伝子を持っている場合、

gene_name start_pos end_pos
gene_A 100 200
gene_B 300 400
gene_C 500 600
gene_D 700 800
gene_E 900 1000

そして、一致する遺伝子を返すために、通常の開始位置と終了位置に一致しない開始位置と終了位置を使用してこのリストを照会したいと考えています。

query_start = 550 query_end = 580 > should return gene_C 
query_start = 110 query end = 180 > should return gene_A

私は自分の道を切り拓こうとしましたが、途方もなく醜い複雑なコードを作成しましたが、これを行うには単純で論理的な方法が必要であることを知っており、適切な質問をするのに苦労していますドキュメント/フォーラム検索の賢明さ.

役立つアドバイスをいただければ幸いです。

ありがとう

4

2 に答える 2

1

これらの値を辞書に入れるのは自然なことです。ここでは、遺伝子名を辞書のキーとして使用し、対応する範囲を値として使用しています。

genes={'gene_A': [100,200],
    'gene_B': [300, 400],
    'gene_C': [500, 600],
    'gene_D': [700, 800],
    'gene_E': [900, 1000]}

#Takes as argument a dictionary of genes to check and a range in the form of a tuple
def gene_query(gene_data,gene_range):
    for gene in gene_data:
        if gene_range[0]>=gene_data[gene][0]:
            if gene_range[1]<=gene_data[gene][1]:
                return gene
    else:
        return "No genes match your query range"


print gene_query(genes, (550, 580))
print gene_query(genes, (110, 180))

ここでは、クエリ範囲に一致する最初の遺伝子の名前を返す Python 関数を作成しましたが、一致する結果をすぐに返すのではなくリストに追加することで、クエリに一致したすべての結果を収集するように簡単に変更できます。

于 2014-07-29T03:58:09.863 に答える
1

まず、タプルのリスト内のすべてのデータを次に示します。

>>> txt='''\
... gene_name start_pos end_pos
... gene_A 100 200
... gene_B 300 400
... gene_C 500 600
... gene_D 700 800
... gene_E 900 1000'''
>>> 
>>> genes=[(name, int(d1), int(d2)) for name, d1, d2 in [line.split() for line in txt.splitlines()[1:]]]
>>> genes
[('gene_A', 100, 200), ('gene_B', 300, 400), ('gene_C', 500, 600), ('gene_D', 700, 800), ('gene_E', 900, 1000)]

それができたら、簡単な例として、フィルターを使用できます。

def query(genes, start, finish):
    return list(filter(lambda t: t[1]<start<t[2] and t[1]<finish<t[2], genes))

>>> query(genes, 550, 580)
[('gene_C', 500, 600)]
>>> query(genes, 110, 180)
[('gene_A', 100, 200)]

またはリスト内包表記:

def query(genes, start, finish):
    return [t[0] for t in genes if t[1]<start<t[2] and t[1]<finish<t[2]]

>>> query(genes, 550, 580)
['gene_C']
>>> query(genes, 110, 180)
['gene_A']

または、bisect モジュールを使用することもできます(genes がソートされたリストの場合)。

最初にリストを並べ替えます。

>>> genes.sort(key=lambda t: (t[1], t[2]))
>>> genes
[('gene_A', 100, 200), ('gene_B', 300, 400), ('gene_C', 500, 600), ('gene_D', 700, 800), ('gene_E', 900, 1000)]

インデックスとして使用できるキー タプルのリストを作成します。

>>> keys=[(t[1], t[2]) for t in genes]
>>> keys
[(100, 200), (300, 400), (500, 600), (700, 800), (900, 1000)]

これで、キー インデックスと bisect を使用して遺伝子をクエリできます。

>>> import bisect
>>> genes[bisect.bisect_left(keys, (550, 580))-1]
('gene_C', 500, 600)
>>> genes[bisect.bisect_left(keys, (110, 180))-1]
('gene_A', 100, 200)

より複雑な例については、SortedCollectionレシピを検討してください。

于 2014-07-29T04:47:50.480 に答える