我有一個采用 DNA 字串的代碼,其中只找到 4 個字符:A、C、T 和 G,例如“ATACAAG”,對于每個字符,如果找到其他 3 個可能的字符。該代碼包括一個字串回圈和另一個可能字串列的回圈。問題是字串很長:多達數十萬個字符,因此速度不快并且計算機變熱(它的風扇開始快速作業)。
我正在尋找一種更快的方法來做到這一點。我嘗試了串列理解,但它仍然很慢。我還嘗試將代碼作為來自 Pandas lambda 的函式呼叫,但每個字串仍然需要大約一分鐘。這是我能得到的最好的嗎?
對于每個字符,代碼在檔案的不同行中記錄 3 個替代項。
編碼:
bases = set(list('ACGT'))
alts = {base: list(bases.difference(base)) for base in bases}
def get_variants(data, output_path): # pb: position base, b: base
[open(output_path f'/{data.symbol}_variants.txt', 'a').writelines(
[f'{data.chromosome}\t{data.end index}\t{data.end index}\t{pb}/{b}\t{data.strand}\n' for b in alts[pb]])
for index, pb in enumerate(data.sequence)]
為“ATACAAG”呼叫函式:
get_variants(pandas.Series({'symbol': 'XYZ', 'sequence': 'ATACAAG', 'chromosome': 12, 'start': 9067664, 'end': 9067671, 'strand': '-'}),
'write_an_existing_output_directory_path_here')
輸出按以下列排列在檔案中:
chromosome number, start position, end position, original character/alternative character, strand (can or -)
它在檔案 XYZ_variants.txt 中生成以下幾行:
12 9067664 9067664 A/T -
12 9067664 9067664 A/G -
12 9067664 9067664 A/C -
12 9067665 9067665 T/A -
12 9067665 9067665 T/G -
12 9067665 9067665 T/C -
12 9067666 9067666 A/T -
12 9067666 9067666 A/G -
12 9067666 9067666 A/C -
12 9067667 9067667 C/T -
12 9067667 9067667 C/A -
12 9067667 9067667 C/G -
12 9067668 9067668 A/T -
12 9067668 9067668 A/G -
12 9067668 9067668 A/C -
12 9067669 9067669 A/T -
12 9067669 9067669 A/G -
12 9067669 9067669 A/C -
12 9067670 9067670 G/T -
12 9067670 9067670 G/A -
12 9067670 9067670 G/C -
謝謝。
uj5u.com熱心網友回復:
這是我將如何做到的。
從資料幀開始:
symbol sequence chromosome start end strand
0 XYZ ATACAAG 12 9067664 9067671 -
我希望explode序列reindex具有 A/C/G/T 的所有組合,并且僅保留初始基數不同的那些
import numpy as np
df2 = df.assign(base=df['sequence'].apply(list)).explode('base').reset_index()
df2 = (df2.reindex(df2.index.repeat(4))
.assign(variant=np.tile(list('ACGT'), len(df2)))
.loc[lambda d: d['base'].ne(d['variant'])]
.assign(var=lambda d:d['base'] '/' d['variant'])
)
中間輸出:
>>> df2.head()
index symbol sequence chromosome start end strand base variant var
0 0 XYZ ATACAAG 12 9067664 9067671 - A C A/C
0 0 XYZ ATACAAG 12 9067664 9067671 - A G A/G
0 0 XYZ ATACAAG 12 9067664 9067671 - A T A/T
1 0 XYZ ATACAAG 12 9067664 9067671 - T A T/A
1 0 XYZ ATACAAG 12 9067664 9067671 - T C T/C
然后匯出:
df2[['start', 'end', 'var', 'strand']].to_csv('variants.txt', sep='\t', index=False, header=None)
示例輸出(第一行):
9067664 9067671 A/C -
9067664 9067671 A/G -
9067664 9067671 A/T -
9067664 9067671 T/A -
9067664 9067671 T/C -
9067664 9067671 T/G -
9067664 9067671 A/C -
9067664 9067671 A/G -
9067664 9067671 A/T -
9067664 9067671 C/A -
優化
現在我們洗掉所有不需要的東西來保持最小的尺寸:
df2 = (df.drop(columns=['symbol', 'chromosome'])
.assign(sequence=df['sequence'].apply(list))
.explode('sequence').reset_index(drop=True)
)
df2 = (df2.reindex(df2.index.repeat(4))
.assign(var=np.tile(list('ACGT'), len(df2)))
.loc[lambda d: d['sequence'].ne(d['var'])]
.assign(var=lambda d:d['sequence'] '/' d['var'])
)
df2[['start', 'end', 'var', 'strand']].to_csv('variants.txt', sep='\t', index=False, header=None)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/367116.html
上一篇:為什么我可以將字串連接到空字串,但不能將字符連接到空字符?
下一篇:在Oracle中將字串評估為條件
