我想提取資料框“B”中第一個和最后一個位置指示的子序列。我想出的演算法是:
- 識別落在 A 位置的 B 行
- 查找位置的相對位置(即移動位置使它們從 0 開始)
- 使用相對位置作為范圍啟動 for 回圈以提取子序列。
上述演算法的問題是運行時。我需要一種替代方法來比現有方法更快地編譯代碼。
期望的輸出:
first last sequences
3 5 ACA
8 12 CGGAG
105 111 ACCCCAA
115 117 TGT
使用的資料框:
import pandas as pd
A = pd.DataFrame({'first.sequence': ['AAACACCCGGAG','ACCACACCCCAAATGTGT'
],'first':[1,100], 'last':[12,117]})
B = pd.DataFrame({'first': [3,8,105,115], 'last':[5,12,111,117]})
uj5u.com熱心網友回復:
一種解決方案可能如下:
out = pd.merge_asof(B, A, on=['last'], direction='forward',
suffixes=('','_y'))
out.loc[:,['first','last']] = \
out.loc[:,['first','last']].sub(out.first_y, axis=0)
out = out.assign(sequences=out.apply(lambda row:
row['first.sequence'][row['first']:row['last'] 1],
axis=1)).drop(['first.sequence','first_y'], axis=1)
out.update(B)
print(out)
first last sequences
0 3 5 ACA
1 8 12 CGGAG
2 105 111 ACCCCAA
3 115 117 TGT
解釋
- 首先,用于
df.merge_asof匹配來自的值與first來自B的first值A。即將3, 8與 匹配1,105, 115并將與 匹配100。現在我們知道哪個字串(序列)需要拆分,我們也知道字串從哪里開始,例如在 index 處1或100而不是 normal處0。 - 我們使用這最后一點資訊來找出字串切片應該從哪里開始和結束。所以,我們這樣做
out.loc[:,['first','last']].sub(out.first_y, axis=0)。例如,我們“重置”3為2(減 1)和105(5減 100)。 - 現在,我們可以
df.apply用來獲取每個序列的字串切片,本質上是遍歷每一行。(如果您的切片將以相同的索引開始和結束,我們可以Series.str.slice改用。 - 最后,我們將結果分配給
out(作為 colsequences),洗掉不再需要的 cols,并使用df.update“重置”列first和last.
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/510294.html
