现在,我正在研究STRING网络
当我想将STRING蛋白替换为Entrez ID时,我看到STRING数据有超过1 M的pandas行。
因此,我尝试将STRING蛋白质ID(如9606.ENSP00000~~)替换为Entrez ID(整数)。
所有的方法都很慢。
但是当我使用这段代码时,所用的时间< 5分钟。
这个代码没有问题吗?
这是密码。”
def replace_string_id(self, data: pd.DataFrame, target_col: str, rename_dict: dict) -> pd.DataFrame:
tmp_list = []
for target, tmp_df in data.groupby(target_col):
if target in rename_dict.keys():
tmp_df[target_col] = rename_dict[target]
tmp_list.append(tmp_df)
else:
continue
# merging
return_df = pd.concat(tmp_list)
return return_df
string_link_df是这样的:
protein1 protein2 combined_score
0 381 9606.ENSP00000379496 155
1 381 9606.ENSP00000314067 197
2 381 9606.ENSP00000263116 222
...
replace_dict是:
{'9606.ENSP00000263100': 1,
'9606.ENSP00000323929': 2,
'9606.ENSP00000443194': 9,
'9606.ENSP00000286479': 10,
'9606.ENSP00000376793': 12,
'9606.ENSP00000450540': 12,
'9606.ENSP00000232892': 13,
...
}
string_renamed = replace_string_id(string_link_df, 'protein2', replace_dict)
”
这段代码比其他方法更快。
--编辑2023-06-023 KST --感谢所有评论我的问题的人。
这是我的全部数据。
**字符串数据:**可在此处下载:https://string-db.org/cgi/download?sessionId=bNSFUedQrsqe&species_text=Homo+sapiens
**链接数据文件名:**9606.protein.links.v11.5.txt.gz
**信息数据文件名:**9606.protein.info.v11.5.txt.gz
你可以使用下面的代码将信息数据转换为dict:
import pandas as pd
from tqdm import tqdm
from pathlib import Path
def main(args):
# read string alias data
string_alias_df = pd.read_csv(args.string_alias_path, sep="\t", dtype={"alias": str}, compression="gzip")
# set target source which have Entrez ID
target_source_list = [
"BLAST_KEGG_GENEID",
"BLAST_UniProt_DR_GeneID",
"Ensembl_HGNC_Entrez_Gene_ID",
"Ensembl_HGNC_Entrez_Gene_ID(supplied_by_NCBI)",
"Ensembl_HGNC_UniProt_ID(supplied_by_UniProt)_DR_GeneID",
"Ensembl_UniProt_DR_GeneID"
]
# make string alias to Entrez
alias_df = []
for string_id, string_id_df in tqdm(string_alias_df.groupby('#string_protein_id')):
target_rows = string_id_df[string_id_df['source'].isin(target_source_list)]
if len(target_rows):
target_row = target_rows.iloc[0]
tmp_series = pd.Series(
data=[string_id, target_row['alias']],
index=["STRING ID", "Entrez"]
)
else:
tmp_series = pd.Series(
data=[string_id, ""],
index=["STRING ID", "Entrez"]
)
alias_df.append(tmp_series)
alias_df = pd.DataFrame(alias_df)
# Need to STRIP
# alias_df['Entrez'] = alias_df['Entrez'].str.strip()
# save
alias_df.to_csv(
args.string_alias_path.parent.joinpath("STRING_Entrez_mapping_table.tsv"),
sep="\t",
header=True,
index=False,
)
pass
if __name__ == "__main__":
import argparse
ref_dir = Path(__file__).parent.parent.joinpath("references", "STRING")
parser = argparse.ArgumentParser()
parser.add_argument("--string_alias_path", type=Path, default=ref_dir.joinpath("9606.protein.aliases.v11.5.txt.gz"))
args = parser.parse_args()
main(args)
原始String数据如:
protein1 protein2 combined_score
0 9606.ENSP00000000233 9606.ENSP00000379496 155
1 9606.ENSP00000000233 9606.ENSP00000314067 197
2 9606.ENSP00000000233 9606.ENSP00000263116 222
3 9606.ENSP00000000233 9606.ENSP00000361263 181
4 9606.ENSP00000000233 9606.ENSP00000409666 270
我需要所有这些列。
我做了两个函数。
一个是西蒙·大卫提出的:
def use_replace(string, target_col, replace_dict) -> None:
data = string.copy()
data = data.replace({target_col: replace_dict})
pass
另一个是我建议的:
def replace_string_id(data: pd.DataFrame, target_col: str, rename_dict: dict) -> pd.DataFrame:
tmp_list = []
for target, tmp_df in data.groupby(target_col):
if target in rename_dict.keys():
tmp_df[target_col] = rename_dict[target]
tmp_list.append(tmp_df)
else:
continue
return_df = pd.concat(tmp_list)
我试图检查use_replace函数的执行时间,但它需要超过1分钟。
use_replace(string,“protein1”,replace_dict)
并且,replace_string_id函数的执行时间为:
%timeit replace_string_id(string, "protein1", replace_dict)
2.43 s ± 5.77 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
所以,我问了这个问题。为什么pandas replace比在超过100万行中使用字典k,v慢,并且想知道这段代码(replace_string_id)是否有其他问题。
谢谢你的关心。
2条答案
按热度按时间tvmytwxo1#
如果我理解你的权利,你是在使用dict替换后,你可以:
其中d是你的dict,例如:
nwnhqdif2#
在您的示例中,
.replace()
的替代方案是将.map()
与.fillna()
结合使用,这比.replace()
快一点。我在下面添加了一个代码示例,它使用两种方法对1200万行执行此操作。在这个简单的实验中,.map()
方法比.replace()
快3倍。**然而,根据此分析,这两种方法对于您的数据集来说都应该足够快。**如果此代码在您的数据集上运行得非常慢,我建议您要么“chunk
”您的数据,要么在加载过程中忽略任何您不需要的列,如本pandas用户指南所述。