跳到主要内容Python RDKit 化学信息学工具库使用指南 | 极客日志PythonAI算法
Python RDKit 化学信息学工具库使用指南
综述由AI生成介绍 Python RDKit 化学信息学工具库的安装与核心功能。内容包括通过 Conda 或 Pip 安装 RDKit,进行分子加载、属性计算、结构可视化、子结构匹配及文件读写。重点展示了分子指纹(Morgan、拓扑)的计算方法,以及基于 Tanimoto 系数的分子相似度分析。同时提供了适配新版 RDKit 的指纹生成器代码,解决旧接口弃用警告问题,适用于药物研发与化学数据分析场景。
修罗18 浏览 RDKit 是一个用于化学信息学的开源工具包,主要用于分子结构的处理、分析和可视化。本文从安装到核心功能提供清晰的示例。
一、安装 RDKit
推荐使用 conda 安装(这是最稳定的方式):
conda create -n rdkit-env python=3.9
conda activate rdkit-env
conda install -c conda-forge rdkit
或者使用 pip 安装:
pip install rdkit
二、核心功能示例
以下是 RDKit 最常用的功能示例,涵盖分子加载、属性计算、结构可视化、子结构匹配等核心场景。
示例 1:基础操作(分子加载、属性计算)
from rdkit import Chem
from rdkit.Chem import Descriptors, Draw
smiles = "CCO"
mol = Chem.MolFromSmiles(smiles)
if mol is None:
raise ValueError("无效的 SMILES 字符串!")
print("=== 分子基本属性 ===")
mw = Descriptors.MolWt(mol)
print(f"分子量:{mw:.2f}")
logp = Descriptors.MolLogP(mol)
print(f"logP: {logp:.2f}")
h_donor = Descriptors.NumHDonors(mol)
print(f"氢键供体数:{h_donor}")
h_acceptor = Descriptors.NumHAcceptors(mol)
print(f"氢键受体数:")
()
()
first_atom = mol.GetAtomWithIdx()
()
()
{h_acceptor}
print
"\n=== 原子和键信息 ==="
print
f"原子总数:{mol.GetNumAtoms()}"
0
print
f"第一个原子:元素符号={first_atom.GetSymbol()}, 原子序数={first_atom.GetAtomicNum()}"
print
f"键总数:{mol.GetNumBonds()}"
示例 2:分子结构可视化
from rdkit import Chem
from rdkit.Chem import Draw
mol = Chem.MolFromSmiles("CCO")
img = Draw.MolToImage(mol, size=(300, 300))
img.save("ethanol_mol.png")
print("单个分子图片已保存为 ethanol_mol.png")
smiles_list = [
("CCO", "Ethanol"),
("CC(=O)O", "Acetic acid"),
("C1=CC=CC=C1", "Benzene"),
("CN1C=NC2=C1C(=O)N(C(=O)N2C)C", "Caffeine")
]
mols = [(Chem.MolFromSmiles(smi), name) for smi, name in smiles_list]
img_grid = Draw.MolsToGridImage(
[mol for mol, name in mols],
molsPerRow=2,
subImgSize=(300, 300),
legends=[name for mol, name in mols]
)
img_grid.save("molecules_grid.png")
print("批量分子网格图已保存为 molecules_grid.png")
示例 3:子结构匹配(查找分子中的特定结构)
from rdkit import Chem
from rdkit.Chem import Draw
aspirin_smiles = "CC(=O)OC1=CC=CC=C1C(=O)O"
aspirin_mol = Chem.MolFromSmiles(aspirin_smiles)
benzene_smarts = "c1ccccc1"
benzene_pattern = Chem.MolFromSmarts(benzene_smarts)
has_benzene = aspirin_mol.HasSubstructMatch(benzene_pattern)
print(f"阿司匹林是否包含苯环:{has_benzene}")
matches = aspirin_mol.GetSubstructMatches(benzene_pattern)
print(f"苯环匹配的原子索引:{matches}")
img = Draw.MolToImage(aspirin_mol, highlightAtoms=matches[0], size=(400, 400))
img.save("aspirin_benzene_highlight.png")
print("高亮子结构的图片已保存为 aspirin_benzene_highlight.png")
示例 4:分子文件读写(支持 SDF、Mol2 等格式)
from rdkit import Chem
mol = Chem.MolFromSmiles("CCO")
w = Chem.SDWriter("ethanol.sdf")
w.write(mol)
w.close()
print("分子已保存为 ethanol.sdf")
suppl = Chem.SDMolSupplier("ethanol.sdf")
for m in suppl:
if m is not None:
print(f"从 SDF 读取的分子 SMILES: {Chem.MolToSmiles(m)}")
三、分子指纹计算
分子指纹是 cheminformatics 中用于表征分子结构、进行相似度比较的核心工具。RDKit 支持多种指纹类型,重点展示 Morgan 指纹、拓扑指纹及相似度分析。
完整示例代码
from rdkit import Chem
from rdkit.Chem import AllChem, DataStructs
from rdkit.Chem.Fingerprints import FingerprintMols
import numpy as np
smiles_dict = {
"Ethanol": "CCO",
"Methanol": "CO",
"Acetic acid": "CC(=O)O",
"Benzene": "C1=CC=CC=C1"
}
mols = {}
for name, smi in smiles_dict.items():
mol = Chem.MolFromSmiles(smi)
if mol is not None:
mols[name] = mol
else:
print(f"警告:{name} 的 SMILES 无效")
print("=== 1. Morgan 指纹计算 ===")
morgan_fps = {}
for name, mol in mols.items():
fp = AllChem.GetMorganFingerprintAsBitVect(mol, radius=2, nBits=1024)
morgan_fps[name] = fp
print(f"{name} Morgan 指纹:长度={fp.GetNumBits()}, 非零位数量={fp.GetNumOnBits()}")
print("\n=== 2. 拓扑指纹计算 ===")
topo_fps = {}
for name, mol in mols.items():
fp = FingerprintMols.FingerprintMol(mol)
topo_fps[name] = fp
print(f"{name} 拓扑指纹:长度={fp.GetNumBits()}, 非零位数量={fp.GetNumOnBits()}")
print("\n=== 3. 指纹转换为数组(前 20 位) ===")
ethanol_morgan_fp = morgan_fps["Ethanol"]
fp_array = np.zeros((1,))
DataStructs.ConvertToNumpyArray(ethanol_morgan_fp, fp_array)
print(f"乙醇 Morgan 指纹前 20 位:{fp_array[:20]}")
print("\n=== 4. 分子相似度分析(Tanimoto 系数) ===")
ref_fp = morgan_fps["Ethanol"]
for name, fp in morgan_fps.items():
similarity = DataStructs.TanimotoSimilarity(ref_fp, fp)
print(f"乙醇 vs {name}: Tanimoto 系数 = {similarity:.4f}")
print("\n=== 5. 批量生成相似度矩阵 ===")
names = list(morgan_fps.keys())
sim_matrix = np.zeros((len(names), len(names)))
for i, name1 in enumerate(names):
for j, name2 in enumerate(names):
sim_matrix[i, j] = DataStructs.TanimotoSimilarity(morgan_fps[name1], morgan_fps[name2])
print("相似度矩阵(行/列:Ethanol, Methanol, Acetic acid, Benzene):")
print(np.round(sim_matrix, 4))
关键部分解释
- Morgan 指纹参数:
radius=2:表示指纹的半径(2 对应 4 层原子,即 ECFP4),是最常用的取值;radius=3 对应 ECFP6。
nBits=1024:指纹的维度(位串长度),常用值还有 2048、4096,维度越高信息越全,但计算成本也越高。
GetMorganFingerprintAsBitVect:生成二进制指纹(位串),也可以用 GetMorganFingerprint 生成计数型指纹(更精细但占用更多内存)。
- 相似度计算:
DataStructs.TanimotoSimilarity:RDKit 内置的 Tanimoto 系数计算函数,是分子相似度比较的行业标准。
- 从示例结果可以看到:乙醇和甲醇的相似度最高(结构最接近),乙醇和苯的相似度最低(结构差异大)。
- 指纹格式转换:
DataStructs.ConvertToNumpyArray:将 RDKit 指纹对象转换为 numpy 数组,方便后续用 sklearn 等库进行机器学习。
四、新版本接口适配说明
较新版本的 RDKit(2023.09+)推荐使用 MorganGenerator 类来生成 Morgan 指纹,旧函数 GetMorganFingerprintAsBitVect 会抛出 Deprecation Warning。以下是适配新版本的代码。
from rdkit import Chem
from rdkit.Chem import DataStructs, rdFingerprintGenerator
import numpy as np
smiles_dict = {
"Ethanol": "CCO",
"Methanol": "CO",
"Acetic acid": "CC(=O)O",
"Benzene": "C1=CC=CC=C1"
}
mols = {}
for name, smi in smiles_dict.items():
mol = Chem.MolFromSmiles(smi)
if mol is not None:
mols[name] = mol
else:
print(f"警告:{name} 的 SMILES 无效")
print("=== 1. Morgan 指纹计算(新版本接口)===")
morgan_gen = rdFingerprintGenerator.GetMorganGenerator(
radius=2,
fpSize=1024,
useChirality=False
)
morgan_fps = {}
for name, mol in mols.items():
fp = morgan_gen.GetFingerprint(mol)
morgan_fps[name] = fp
print(f"{name} Morgan 指纹:长度={fp.GetNumBits()}, 非零位数量={fp.GetNumOnBits()}")
print("\n=== 2. 拓扑指纹计算 ===")
topo_fps = {}
for name, mol in mols.items():
fp = Chem.Fingerprints.FingerprintMols.FingerprintMol(mol)
topo_fps[name] = fp
print(f"{name} 拓扑指纹:长度={fp.GetNumBits()}, 非零位数量={fp.GetNumOnBits()}")
print("\n=== 3. 指纹转换为数组(前 20 位) ===")
ethanol_morgan_fp = morgan_fps["Ethanol"]
fp_array = np.zeros((1,))
DataStructs.ConvertToNumpyArray(ethanol_morgan_fp, fp_array)
print(f"乙醇 Morgan 指纹前 20 位:{fp_array[:20]}")
print("\n=== 4. 分子相似度分析(Tanimoto 系数) ===")
ref_fp = morgan_fps["Ethanol"]
for name, fp in morgan_fps.items():
similarity = DataStructs.TanimotoSimilarity(ref_fp, fp)
print(f"乙醇 vs {name}: Tanimoto 系数 = {similarity:.4f}")
print("\n=== 5. 批量生成相似度矩阵 ===")
names = list(morgan_fps.keys())
sim_matrix = np.zeros((len(names), len(names)))
for i, name1 in enumerate(names):
for j, name2 in enumerate(names):
sim_matrix[i, j] = DataStructs.TanimotoSimilarity(morgan_fps[name1], morgan_fps[name2])
print("相似度矩阵(行/列:Ethanol, Methanol, Acetic acid, Benzene):")
print(np.round(sim_matrix, 4))
关键修改点解释
- 核心替换:
- 旧代码:
AllChem.GetMorganFingerprintAsBitVect(mol, radius=2, nBits=1024)
- 新代码:先初始化
rdFingerprintGenerator.GetMorganGenerator(),再调用 GetFingerprint(mol)
- 对应参数:
nBits → fpSize,其余参数(如 radius)保持一致。
- 新接口优势:
- 消除 deprecation 警告,适配 RDKit 新版本;
- 生成器对象可复用(批量计算多个分子时更高效);
- 支持更多扩展参数(如
useChirality 控制手性、useBondTypes 控制是否考虑键类型)。
- 结果一致性:不同 RDKit 版本的指纹哈希算法细节略有差异,但相似度计算结果不会受影响。
总结
- 核心基础:RDKit 最核心的是
Chem.MolFromSmiles() 创建分子对象,所有操作都基于这个对象展开。
- 常用功能:可快速计算分子理化性质(分子量、logP 等)、可视化分子结构、匹配子结构、读写分子文件。
- 关键注意点:使用前需检查分子对象是否为
None(避免无效 SMILES),可视化需确保安装了 PIL/Pillow 依赖。
- 版本兼容:建议使用
rdFingerprintGenerator.GetMorganGenerator() 替代旧的指纹生成函数以消除警告。
- 实用技巧:指纹可转换为 numpy 数组,用于分子聚类、分类、虚拟筛选等机器学习任务。
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- RSA密钥对生成器
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
- Mermaid 预览与可视化编辑
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
- 随机西班牙地址生成器
随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
- Gemini 图片去水印
基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online