2014-10-30 41 views
3

我从数据库中获得DNA或蛋白质序列。序列是对齐的,所以虽然我总是知道一个输入序列,但它经常被截断,并且以添加“ - ”字符的形式包含空位。我首先想在查询字符串中找到一个区域。在这种情况下,正则表达式搜索非常有意义。然后我想从其他对齐的字符串中提取等价区域(我在这里将它们命名为“标记”和“命中”)。由于序列是对齐的,我想在所有字符串中的区域将具有相同的开始和结束。有一种简单的方法来获取熊猫数据框中正则表达式匹配的开始和停止吗?如何使用python熊猫数据框找到正则表达式匹配的开始和结束?

import pandas as pd 
import re 
q1,q2,q3 = 'MPIMGSSVYITVELAIAVLAILG','MPIMGSSVYITVELAIAVLAILG','MPI-MGSSVYITVELAIAVLAIL' 
m1,m2,m3 = '|| || ||||||||||||||||','|| | ||| :|| || |:: |','||: ::|: :||||| |:: ' 
h1,h2,h3 = 'MPTMGFWVYITVELAIAVLAILG','MP-NSSLVYIGLELVIACLSVAG','MPLETQDALYVALELAIAALSVA' 
#create a pandas dataframe to hold the aligned sequences 
df = pd.DataFrame({'query':[q1,q2,q3],'markup':[m1,m2,m3],'hit':[h1,h2,h3]}) 
#create a regex search string to find the appropriate subset in the query sequence, 
desired_region_from_query = 'PIMGSS' 
regex_desired_region_from_query = '(P-*I-*M-*G-*S-*S-*)' 

大熊猫有一个很好的提取功能切出从查询匹配的序列:

df['query'].str.extract(regex_desired_region_from_query) 

不过,我需要为了从标记提取等效区域比赛的起点和终点并击中列。对于单个字符串,完成如下:

match = re.search(regex_desired_region_from_query, df.loc[2,'query']) 
sliced_hit = df.loc[2,'hit'][match.start():match.end()] 
sliced_hit 
Out[3]:'PLETQDA' 

我目前的解决方法如下。 (编辑,包括nhahtdh的建议,并因此避免搜索的两倍。)

#define function to obtain regex output (start, stop, etc) as a tuple 
def get_regex_output(x): 
    m = re.search(regex_desired_region_from_query, x) 
    return (m.start(), m.end()) 
#apply function 
df['regex_output_tuple'] = df['query'].apply(get_regex_output) 
#convert the tuple into two separate columns 
columns_from_regex_output = ['start','end']  
for n, col in enumerate(columns_from_regex_output): 
    df[col] = df['regex_output_tuple'].apply(lambda x: x[n]) 
#delete the unnecessary column 
df = df.drop('regex_output_tuple', axis=1) 

现在我想用获取的开始和结束的整数切片中的字符串。 这段代码会很好:
df.sliced = df.string[df.start:df.end]
但我认为它不存在。相反,我不得不再次使用lambda函数:

#create slice functions 
fn_slice_hit = lambda x : x['hit'][x['start']:x['end']] 
fn_slice_markup = lambda x : x['markup'][x['start']:x['end']] 

#apply the slice functions 
df['sliced_markup'] = df.apply(fn_slice_markup, axis = 1) 
df['sliced_hit'] = df.apply(fn_slice_hit, axis = 1) 
print(df) 

         hit     markup     query start end sliced_markup sliced_hit 
0 MPTMGFWVYITVELAIAVLAILG || || |||||||||||||||| MPIMGSSVYITVELAIAVLAILG  1 7  | ||  PTMGFW 
1 MP-NSSLVYIGLELVIACLSVAG || | ||| :|| || |:: | MPIMGSSVYITVELAIAVLAILG  1 7  | |  P-NSSL 
2 MPLETQDALYVALELAIAALSVA ||: ::|: :||||| |:: MPI-MGSSVYITVELAIAVLAIL  1 8  |: : PLETQDA 

做熊猫.match,.extract,.findall功能有。开始()或.END()属性的相同呢?
有没有办法更优雅切片?
任何帮助,将不胜感激!

+0

我不确定此链接到常规的Python正则表达式文档可以帮助我。问题是高效地找到5000行熊猫数组中每个字符串的开始和结束索引。 – 2014-10-30 17:23:32

+0

而不是运行正则表达式两次以获得启动和停止索引,你可以做'(df ['start'],df ['end'])= df ['query']。apply(func)'func是一个返回开始和结束索引而不必运行正则表达式两次的函数? – nhahtdh 2014-10-30 17:46:13

+0

你能告诉我这个函数返回开始和结束索引,而不必运行正则表达式两次吗? – 2014-10-31 10:48:05

回答

1

我不认为这存在于熊猫,但会是一个很好的补充。转至https://github.com/pydata/pandas/issues并添加新的问题。解释一下你希望看到的增强功能。

对于.start()和.end()方法,那些对extract()方法可能更有意义。如果str.extract(pat,start_index = True),则返回开始索引的序列或数据框,而不是捕获组的值。 end_index = True也一样。这些可能需要互相排斥。

我也喜欢你的

df.sliced = df.string[df.start:df.end] 

建议大熊猫已经具备了str.slice方法

df.sliced = df.string.str.slice(1, -1) 

但是这些必须是整数。在Github上添加一个单独的问题,让str.slice方法采用系列对象并应用元素明智的方式。

对不起没有比你的lambda hack更好的解决方案,但它的用例就是帮助驱动Pandas变得更好。

+0

谢谢jkitchen。这些问题现在在熊猫github存储库上。正则表达式的问题在这里:https://github.com/pydata/pandas/issues/8747和切片的建议是在这里https://github.com/pydata/pandas/issues/8748 – 2014-11-06 17:35:48

相关问题