gpt4 book ai didi

python - 替换 pandas 数据框中的字符串

转载 作者:行者123 更新时间:2023-11-30 22:37:34 27 4
gpt4 key购买 nike

我有一个pandas.DataFrame,其中包含 bool 规则,表示 enzyme 是否表达。有些规则很简单(表达取决于 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

...

字典对象包含有关基因表达的信息:(1=expr,0=not expr)

>>translation

'HGNC:80':1
'HGNC:2602':0
etc...

我想将“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”并评估 bool 规则。

有什么建议吗?

编辑:

使用 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 的建议

最佳答案

输入翻译可以通过

完成
>>>for_eval = {k+'(?![0-9])': str(v) for k, v in translation.items()}
>>>gprs['translation'] = gprs['rule'].replace(for_eval, regex=True)

说明:

第一行

>>>for_eval = {k+'(?![0-9])': str(v) for k, v in translation.items()}

01交换为其字符串形式,分别为'0''1',准备将它们插入到第二行的字符串中。将“(?![0-9])”添加到键中会检查并忽略后面有更多数字的匹配,从而避免仅与键的第一部分匹配。

第二行

>>>gprs['translation'] = gprs['rule'].replace(for_eval, regex=True)

在 pandas 中将替换作为列操作执行,而不是在 python 中迭代每一行,对于较大的数据集(例如本例中的 30 个或更多条目),速度要慢得多。

如果没有 regex=True,这只能在完全匹配的情况下起作用,这会产生与您在尝试实现较长规则时遇到的相同问题。

示例,测试用例归功于 u/Stephen Rauch:

In [3]:translation = {
'HGNC:80': 1,
'HGNC:249': 1,
'HGNC:250': 1,
'HGNC:251': 0,
'HGNC:252': 1,
'HGNC:253': 0,
'HGNC:255': 1,
'HGNC:256': 1,
'HGNC:549': 0,
'HGNC:550': 1,
'HGNC:2602': 0,
'HGNC:16354': 1,
}

In [4]:gprs = pd.DataFrame([
('HGNC:550', 1),
('HGNC:2602', 0),
('HGNC:253 or HGNC:549', 0),
('HGNC:549 or HGNC:550 or HGNC:80', 1),
('HGNC:549 or (HGNC:550 and HGNC:2602)', 0),
('HGNC:549 or (HGNC:550 and HGNC:16354)', 1),
('HGNC:16354 or (HGNC:249 and HGNC:250) or (HGNC:249 and HGNC:251)', 1)
], columns = ['rule', 'target'])

In [5]:for_eval = {k: str(v) for k, v in translation.items()}

In [6]:gprs['translation'] = gprs['rule'].replace(for_eval, regex=True)

In [7]:gprs['translation']

Out[7]:
0 1
1 0
2 0 or 0
3 0 or 1 or 1
4 0 or (1 and 0)
5 0 or (1 and 1)
6 1 or (1 and 1) or (1 and 0)
Name: translation, dtype: object

对于您稍后要查看的第二部分,eval(如 u/Stephen Rauch 的答案中提到和详细说明的)可用于计算生成的字符串中包含的表达式。为此,pd.Series.map 可用于比使用 iterrows 更快地对序列应用元素级操作。在这里,看起来像这样

In [10]:gprs['translation'].map(eval)
Out[10]:
0 1
1 0
2 0
3 1
4 0
5 1
6 1
Name: translation, dtype: int64

或者,如果试图尽力提高性能,可以选择在输出上使用正则表达式模式匹配而不是映射。它变得更具体地取决于您的规则的措辞方式,但如果它们的格式都像您帖子中的三个一样好,“and”都是成对且带括号的,没有嵌套,那么

# set any 'and' term with a zero in it to zero
>>>ands = gprs['translation'].str.replace('0 and \d|\d and 0', '0')
# if any ones remain, only 'or's and '1 and 1' statements are left
>>>ors = ands.replace('1', 1, regex=True)
# faster to force it to numeric than to search the remaining terms for zeros
>>>out = pd.to_numeric(ors, errors='coerce').fillna(0)
>>>out
0 1.0
1 0.0
2 0.0
3 1.0
4 0.0
5 1.0
6 1.0
Name: translation, dtype: float64

使用 timeit 模块检查,对于数千行以上的情况,速度应该快五倍左右,盈亏平衡点大约为 60 或 70 个条目。

关于python - 替换 pandas 数据框中的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43849666/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com