我有一个pandas.DataFrame
,它包含布尔规则来判断一个酶是否被表达。有些规则很简单(表达取决于1个基因),有些则更复杂(表达取决于多个基因)
>>gprs.head()
Out[362]:
Rxn rule
0 13DAMPPOX HGNC:549 or HGNC:550 or HGNC:80
6 24_25VITD2Hm HGNC:2602
8 25VITD2Hm HGNC:16354 or (HGNC:249 and HGNC:250) or (HGNC:249 and HGNC:251) or (HGNC:250 and HGNC:251) or HGNC:252 or HGNC:253 or HGNC:255 or HGNC:256
...
dict对象包含有关基因表达的信息:(1=expr,0=not expr)
^{pr2}$我想将“translation”对象中包含的表达式信息替换为我的“gprs”pandas.DataFrame
。到目前为止,我已经:
for index, row in gprs.iterrows():
row['rule']=row['rule'].replace(r'(', "")
row['rule']=row['rule'].replace(r')', "")
ruleGenes=re.split(" and | or ",(row['rule']))
for gene in ruleGenes:
if re.match("HGNC:HGNC:", gene):
gene=gene[5:]
try:
gprs=gprs.replace(gene,translation[gene])
except:
print 'error in ', gene
else:
try:
gprs=gprs.replace(gene,translation[gene])
except:
print 'error in ', gene
这仅在规则很简单(1个元素)时有效,但对于更复杂的规则则失败:
>>gprs.head()
0 13DAMPPOX HGNC:549 or HGNC:550 or HGNC:80
6 24_25VITD2Hm 0
7 24_25VITD3Hm HGNC:16354 or (HGNC:249 and HGNC:250) or (HGNC:249 and HGNC:251) or (HGNC:250 and HGNC:251) or HGNC:252 or HGNC:253 or HGNC:255 or HGNC:256
最后,我想用max()函数替换“or”,用min()函数替换“and”,并计算布尔规则。在
有什么建议吗?在
编辑:
当使用EFT的代码时,当一个字符串是另一个字符串的子字符串时会出现问题,例如:HGNC:54人'和'HGNC:549'
>>translation
'HGNC:54':0
'HGNC:549':1
结果:
>>gprs.head(1)
Rxn rule translation
0 13DAMPPOX HGNC:549 or HGNC:550 or HGNC:80 09 or 1 or 0
我应该如何只替换整个字符串而不是子字符串?在
编辑编辑:
它适用于:
for_eval = {k+'(?![0-9])' : str(v) for k, v in translation.items()}
gprs['translation'] = gprs['rule'].replace(for_eval, regex=True)
谢谢EFT的建议
这里有一种方法可以用来计算这种酶是否被表达。在
代码:
它是如何工作的?
这里的想法是采用如下规则:
^{pr2}$把它改成:
IE:将
HGNC:1234
等值的所有实例更改为translation_table["HGNC:1234"]
。在这将产生一个字符串,这是一个合法的python表达式。结果表达式可以用
eval()
计算。在测试代码:
输入翻译可以用
说明:
第一行
^{pr2}$将}分别交换其字符串形式},为将它们插入第二行的字符串做准备。添加'(?![0-9]),则检查并忽略后面有更多数字的匹配项,从而避免只在键的第一部分匹配。在
0
和{'0'
和{第二条线
在pandas中,将替换作为列操作执行,而不是在python中迭代每一行,对于更大的数据集(本例中为30个或更多个条目),速度要慢得多。在
如果没有
regex=True
,这只会在完全匹配的情况下起作用,这将导致您在尝试实现较长规则时遇到的相同问题。在例如,将测试用例归功于u/Stephen Rauch:
对于后面要看的第二部分,
eval
,正如u/Stephen Rauch的答案中所提到和阐述的,可以用来计算所生成的字符串中包含的表达式。为此,pd.Series.map
可用于对序列应用元素操作,比使用iterrows
更快。这里,看起来像这样或者,如果试图弥补性能的最后一点,可以选择在输出上使用regex模式匹配而不是map。它变得更加依赖于你的规则是如何措辞的,但是如果它们的格式都像你帖子里的三个一样,都是成对的、带圆括号的,没有嵌套,那么
应该快5倍左右,使用timeit模块检查,超过几千行,盈亏平衡点在60或70个条目左右。在
相关问题 更多 >
编程相关推荐