You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RDKit中聚合物SMILES转特征向量:含‘*C*’结构时出现NaN值求解

问题解决:带通配符的SMILES生成特征向量返回NaN的处理

原因分析

你遇到的问题是因为*在SMILES中是通配符,代表任意未知原子。RDKit的大多数分子描述符(比如分子量、拓扑指数等)依赖明确的原子属性(原子量、价态等),通配符的原子没有这些明确属性,导致部分描述符计算失败,返回NaN或无穷大值。你的computeDescriptors函数会因为检测到非有限值(NaN/inf)而返回None。

另外你的代码里smiles列表存在语法错误,需要修正为合法的Python列表格式。


解决方案

根据你的使用场景,有以下几种处理方式:

1. 替换通配符为具体原子(推荐,若已知端基)

如果你的聚合物重复单元的端基是明确的(比如氢原子),可以将*替换为具体原子,让结构完整,这样所有描述符都能正常计算。

2. 过滤/填充NaN值

保留能正常计算的描述符,对NaN值进行填充(比如用所有样本的均值、中位数,或者0),避免直接返回None。

3. 使用RDKit标准的聚合物连接点表示

RDKit支持用[*]表示聚合物重复单元的连接点,替换*为[*]可以让RDKit更好地识别结构,部分描述符能正常计算。


代码示例

修正基础语法错误

首先修正smiles列表的语法错误:

smiles = ['*C*', 'C1CCCC1', 'CCCCCC', 'CCCC(C)C']

方案1:替换通配符为H原子

import numpy as np
from rdkit import Chem
from rdkit.Chem import Descriptors
from rdkit.ML.Descriptors import MoleculeDescriptors

descriptors = [desc[0] for desc in Descriptors._descList]
calculator = MoleculeDescriptors.MolecularDescriptorCalculator(descriptors)

def computeDescriptors(mol, calculator):
    res = np.array(calculator.CalcDescriptors(mol))
    # 检查是否有非有限值,用均值填充NaN/inf
    mask = np.isfinite(res)
    if not np.all(mask):
        res[~mask] = np.mean(res[mask])
    return res

# 替换通配符为H
processed_smiles = [s.replace('*', 'H') for s in smiles]
mol_objects = [Chem.MolFromSmiles(smile) for smile in processed_smiles]

features = [computeDescriptors(x, calculator) for x in mol_objects]

print(features)

方案2:过滤无法计算的描述符

只保留对通配符结构能正常计算的描述符:

import numpy as np
from rdkit import Chem
from rdkit.Chem import Descriptors
from rdkit.ML.Descriptors import MoleculeDescriptors

# 先测试哪些描述符能处理*C*结构
test_mol = Chem.MolFromSmiles('*C*')
valid_descriptors = []
for desc_name, _ in Descriptors._descList:
    try:
        desc_func = getattr(Descriptors, desc_name)
        val = desc_func(test_mol)
        if np.isfinite(val):
            valid_descriptors.append(desc_name)
    except:
        continue

# 使用过滤后的描述符计算器
calculator = MoleculeDescriptors.MolecularDescriptorCalculator(valid_descriptors)

def computeDescriptors(mol, calculator):
    return np.array(calculator.CalcDescriptors(mol))

mol_objects = [Chem.MolFromSmiles(smile) for smile in smiles]
features = [computeDescriptors(x, calculator) for x in mol_objects]

print(f"保留的有效描述符数量:{len(valid_descriptors)}")
print(features)

方案3:使用标准聚合物连接点表示

import numpy as np
from rdkit import Chem
from rdkit.Chem import Descriptors
from rdkit.ML.Descriptors import MoleculeDescriptors

descriptors = [desc[0] for desc in Descriptors._descList]
calculator = MoleculeDescriptors.MolecularDescriptorCalculator(descriptors)

def computeDescriptors(mol, calculator):
    res = np.array(calculator.CalcDescriptors(mol))
    # 填充NaN为均值
    mask = np.isfinite(res)
    if len(res[mask]) > 0:
        res[~mask] = np.mean(res[mask])
    return res

# 将*替换为[*],符合RDKit聚合物连接点规范
processed_smiles = [s.replace('*', '[*]') for s in smiles]
mol_objects = [Chem.MolFromSmiles(smile) for smile in processed_smiles]

features = [computeDescriptors(x, calculator) for x in mol_objects]

print(features)

内容的提问来源于stack exchange,提问作者str

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 19:09:51