使用RDKit计算DataFrame分子Tanimoto系数报错,寻求解决方法
解决RDKit计算分子两两Tanimoto系数的报错问题
分子数据
{'name': ['16β-hydro-ent-kauran-17-oic acid ', '16α-hydro-entkauran-17-oic acid ', 'ent-kaur-16-en-19-oic acid', '16β,17-dihydroxy-ent-kauran-19-oic acid ', 'annomontacin'], 'canonical_smile': ['CC1(CCCC2(C1CCC34C2CCC(C3)C(C4)C(=O)O)C)C', 'CC1(CCCC2(C1CCC34C2CCC(C3)C(C4)C(=O)O)C)C', 'CC12CCCC(C1CCC34C2CCC(C3)C(=C)C4)(C)C(=O)O', 'CC12CCCC(C1CCC34C2CCC(C3)C(C4)(CO)O)(C)C(=O)O', 'CCCCCCCCCCCCC(C1CCC(O1)C(CCCCCCC(CCCCCC(CC2=CC(OC2=O)C)O)O)O)O']}
报错原因
你调用DataStructs.BulkTanimotoSimilarity时参数类型不符合要求:该函数的设计逻辑是单个指纹对象对比一组指纹列表,但你传入了两个Pandas Series,与函数的C++签名不匹配。
修正后的代码
import pandas as pd import itertools from rdkit import Chem, DataStructs from rdkit.Chem import PandasTools, rdFingerprintGenerator # 初始化原始数据 raw_data = {'name': ['16β-hydro-ent-kauran-17-oic acid ', '16α-hydro-entkauran-17-oic acid ', 'ent-kaur-16-en-19-oic acid', '16β,17-dihydroxy-ent-kauran-19-oic acid ', 'annomontacin'], 'canonical_smile': ['CC1(CCCC2(C1CCC34C2CCC(C3)C(C4)C(=O)O)C)C', 'CC1(CCCC2(C1CCC34C2CCC(C3)C(C4)C(=O)O)C)C', 'CC12CCCC(C1CCC34C2CCC(C3)C(=C)C4)(C)C(=O)O', 'CC12CCCC(C1CCC34C2CCC(C3)C(C4)(CO)O)(C)C(=O)O', 'CCCCCCCCCCCCC(C1CCC(O1)C(CCCCCCC(CCCCCC(CC2=CC(OC2=O)C)O)O)O)O']} df = pd.DataFrame(raw_data) # 生成所有两两SMILES组合 df3 = pd.DataFrame(list(itertools.combinations(df['canonical_smile'].unique(), 2)), columns=['canonical_smile1', 'canonical_smile2']).dropna() # 添加ROMol分子对象列 PandasTools.AddMoleculeColumnToFrame(df3, 'canonical_smile1', 'ROMol1', includeFingerprints=True) PandasTools.AddMoleculeColumnToFrame(df3, 'canonical_smile2', 'ROMol2', includeFingerprints=True) # 初始化Morgan指纹生成器 morgan_gen = rdFingerprintGenerator.GetMorganGenerator(radius=2, fpSize=2048) # 为每个分子生成Morgan指纹 df3["morgan1"] = df3["ROMol1"].apply(lambda x: morgan_gen.GetFingerprint(x)) df3["morgan2"] = df3["ROMol2"].apply(lambda x: morgan_gen.GetFingerprint(x)) # 逐行计算两两分子的Tanimoto系数 df3["tanimoto_morgan"] = df3.apply(lambda row: DataStructs.TanimotoSimilarity(row['morgan1'], row['morgan2']), axis=1) # 输出结果 print(df3[['canonical_smile1', 'canonical_smile2', 'tanimoto_morgan']])
关键修改点
- 显式初始化Morgan指纹生成器,避免批量调用的歧义
- 使用
apply逐行处理指纹对,调用DataStructs.TanimotoSimilarity()计算单个两两相似度(BulkTanimotoSimilarity适用于单个指纹对比多组指纹的场景) - 修正原代码中不必要的缩进问题
内容的提问来源于stack exchange,提问作者jacobdavis
相关产品推荐
相关产品推荐

