Datamol化学信息学技能Skill datamol

Datamol 是一个 Python 库,用于简化分子化学信息学操作,包括 SMILES 解析、标准化、描述符计算、指纹生成、聚类分析等。关键词:化学信息学、分子数据处理、Python、RDKit、药物发现、数据分析、机器学习、AI 应用。

数据分析 0 次安装 0 次浏览 更新于 3/20/2026

名称: datamol 描述: “RDKit 的 Pythonic 包装器,具有简化接口和合理默认值。适用于标准药物发现:SMILES 解析、标准化、描述符、指纹、聚类、3D 构象体、并行处理。返回原生 rdkit.Chem.Mol 对象。对于高级控制或自定义参数,请直接使用 rdkit。”

Datamol 化学信息学技能

概述

Datamol 是一个 Python 库,提供轻量级、Pythonic 的抽象层,用于分子化学信息学,基于 RDKit。通过合理默认值、高效并行化和现代 I/O 功能,简化复杂分子操作。所有分子对象都是原生 rdkit.Chem.Mol 实例,确保与 RDKit 生态系统完全兼容。

关键能力:

  • 分子格式转换(SMILES、SELFIES、InChI)
  • 结构标准化和净化
  • 分子描述符和指纹
  • 3D 构象体生成和分析
  • 聚类和多样性选择
  • 骨架和片段分析
  • 化学反应应用
  • 可视化和对齐
  • 批处理并行化
  • 通过 fsspec 支持云存储

安装和设置

指导用户安装 datamol:

uv pip install datamol

导入约定:

import datamol as dm

核心工作流

1. 基本分子处理

从 SMILES 创建分子:

import datamol as dm

# 单个分子
mol = dm.to_mol("CCO")  # 乙醇

# 从 SMILES 列表
smiles_list = ["CCO", "c1ccccc1", "CC(=O)O"]
mols = [dm.to_mol(smi) for smi in smiles_list]

# 错误处理
mol = dm.to_mol("invalid_smiles")  # 返回 None
if mol is None:
    print("解析 SMILES 失败")

将分子转换为 SMILES:

# 规范 SMILES
smiles = dm.to_smiles(mol)

# 异构 SMILES(包括立体化学)
smiles = dm.to_smiles(mol, isomeric=True)

# 其他格式
inchi = dm.to_inchi(mol)
inchikey = dm.to_inchikey(mol)
selfies = dm.to_selfies(mol)

标准化和净化(始终建议用于用户提供的分子):

# 净化分子
mol = dm.sanitize_mol(mol)

# 完全标准化(建议用于数据集)
mol = dm.standardize_mol(
    mol,
    disconnect_metals=True,
    normalize=True,
    reionize=True
)

# 直接处理 SMILES 字符串
clean_smiles = dm.standardize_smiles(smiles)

2. 读取和写入分子文件

参考 references/io_module.md 获取全面的 I/O 文档。

读取文件:

# SDF 文件(化学中最常见)
df = dm.read_sdf("compounds.sdf", mol_column='mol')

# SMILES 文件
df = dm.read_smi("molecules.smi", smiles_column='smiles', mol_column='mol')

# 带有 SMILES 列的 CSV
df = dm.read_csv("data.csv", smiles_column="SMILES", mol_column="mol")

# Excel 文件
df = dm.read_excel("compounds.xlsx", sheet_name=0, mol_column="mol")

# 通用读取器(自动检测格式)
df = dm.open_df("file.sdf")  # 支持 .sdf、.csv、.xlsx、.parquet、.json

写入文件:

# 保存为 SDF
dm.to_sdf(mols, "output.sdf")
# 或从 DataFrame
dm.to_sdf(df, "output.sdf", mol_column="mol")

# 保存为 SMILES 文件
dm.to_smi(mols, "output.smi")

# 带有渲染分子图像的 Excel
dm.to_xlsx(df, "output.xlsx", mol_columns=["mol"])

远程文件支持(S3、GCS、HTTP):

# 从云存储读取
df = dm.read_sdf("s3://bucket/compounds.sdf")
df = dm.read_csv("https://example.com/data.csv")

# 写入云存储
dm.to_sdf(mols, "s3://bucket/output.sdf")

3. 分子描述符和性质

参考 references/descriptors_viz.md 获取详细描述符文档。

计算单个分子的描述符:

# 获取标准描述符集
descriptors = dm.descriptors.compute_many_descriptors(mol)
# 返回: {'mw': 46.07, 'logp': -0.03, 'hbd': 1, 'hba': 1,
#           'tpsa': 20.23, 'n_aromatic_atoms': 0, ...}

批处理描述符计算(建议用于数据集):

# 并行计算所有分子
desc_df = dm.descriptors.batch_compute_many_descriptors(
    mols,
    n_jobs=-1,      # 使用所有 CPU 核心
    progress=True   # 显示进度条
)

特定描述符:

# 芳香性
n_aromatic = dm.descriptors.n_aromatic_atoms(mol)
aromatic_ratio = dm.descriptors.n_aromatic_atoms_proportion(mol)

# 立体化学
n_stereo = dm.descriptors.n_stereo_centers(mol)
n_unspec = dm.descriptors.n_stereo_centers_unspecified(mol)

# 灵活性
n_rigid = dm.descriptors.n_rigid_bonds(mol)

药物相似性过滤(Lipinski 五规则):

# 过滤化合物
def is_druglike(mol):
    desc = dm.descriptors.compute_many_descriptors(mol)
    return (
        desc['mw'] <= 500 and
        desc['logp'] <= 5 and
        desc['hbd'] <= 5 and
        desc['hba'] <= 10
    )

druglike_mols = [mol for mol in mols if is_druglike(mol)]

4. 分子指纹和相似性

生成指纹:

# ECFP(扩展连通性指纹,默认)
fp = dm.to_fp(mol, fp_type='ecfp', radius=2, n_bits=2048)

# 其他指纹类型
fp_maccs = dm.to_fp(mol, fp_type='maccs')
fp_topological = dm.to_fp(mol, fp_type='topological')
fp_atompair = dm.to_fp(mol, fp_type='atompair')

相似性计算:

# 集合内的成对距离
distance_matrix = dm.pdist(mols, n_jobs=-1)

# 两个集合之间的距离
distances = dm.cdist(query_mols, library_mols, n_jobs=-1)

# 查找最相似分子
from scipy.spatial.distance import squareform
dist_matrix = squareform(dm.pdist(mols))
# 较低距离 = 较高相似性(Tanimoto 距离 = 1 - Tanimoto 相似性)

5. 聚类和多样性选择

参考 references/core_api.md 获取聚类细节。

Butina 聚类:

# 通过结构相似性聚类分子
clusters = dm.cluster_mols(
    mols,
    cutoff=0.2,    # Tanimoto 距离阈值(0=相同,1=完全不同)
    n_jobs=-1      # 并行处理
)

# 每个聚类是分子索引列表
for i, cluster in enumerate(clusters):
    print(f"聚类 {i}: {len(cluster)} 个分子")
    cluster_mols = [mols[idx] for idx in cluster]

重要: Butina 聚类构建完整距离矩阵 - 适用于约 1000 个分子,不适用于 10,000 以上。

多样性选择:

# 选择多样子集
diverse_mols = dm.pick_diverse(
    mols,
    npick=100  # 选择 100 个多样分子
)

# 选择聚类质心
centroids = dm.pick_centroids(
    mols,
    npick=50   # 选择 50 个代表分子
)

6. 骨架分析

参考 references/fragments_scaffolds.md 获取完整骨架文档。

提取 Murcko 骨架:

# 获取 Bemis-Murcko 骨架(核心结构)
scaffold = dm.to_scaffold_murcko(mol)
scaffold_smiles = dm.to_smiles(scaffold)

基于骨架的分析:

# 按骨架分组化合物
from collections import Counter

scaffolds = [dm.to_scaffold_murcko(mol) for mol in mols]
scaffold_smiles = [dm.to_smiles(s) for s in scaffolds]

# 统计骨架频率
scaffold_counts = Counter(scaffold_smiles)
most_common = scaffold_counts.most_common(10)

# 创建骨架到分子映射
scaffold_groups = {}
for mol, scaf_smi in zip(mols, scaffold_smiles):
    if scaf_smi not in scaffold_groups:
        scaffold_groups[scaf_smi] = []
    scaffold_groups[scaf_smi].append(mol)

基于骨架的训练/测试分割(用于机器学习):

# 确保训练和测试集具有不同骨架
scaffold_to_mols = {}
for mol, scaf in zip(mols, scaffold_smiles):
    if scaf not in scaffold_to_mols:
        scaffold_to_mols[scaf] = []
    scaffold_to_mols[scaf].append(mol)

# 将骨架分割为训练/测试
import random
scaffolds = list(scaffold_to_mols.keys())
random.shuffle(scaffolds)
split_idx = int(0.8 * len(scaffolds))
train_scaffolds = scaffolds[:split_idx]
test_scaffolds = scaffolds[split_idx:]

# 获取每个分割的分子
train_mols = [mol for scaf in train_scaffolds for mol in scaffold_to_mols[scaf]]
test_mols = [mol for scaf in test_scaffolds for mol in scaffold_to_mols[scaf]]

7. 分子片段化

参考 references/fragments_scaffolds.md 获取片段化细节。

BRICS 片段化(16 种键类型):

# 片段化分子
fragments = dm.fragment.brics(mol)
# 返回: 带有连接点如 '[1*]CCN' 的片段 SMILES 集合

RECAP 片段化(11 种键类型):

fragments = dm.fragment.recap(mol)

片段分析:

# 查找化合物库中的常见片段
from collections import Counter

all_fragments = []
for mol in mols:
    frags = dm.fragment.brics(mol)
    all_fragments.extend(frags)

fragment_counts = Counter(all_fragments)
common_frags = fragment_counts.most_common(20)

# 基于片段的评分
def fragment_score(mol, reference_fragments):
    mol_frags = dm.fragment.brics(mol)
    overlap = mol_frags.intersection(reference_fragments)
    return len(overlap) / len(mol_frags) if mol_frags else 0

8. 3D 构象体生成

参考 references/conformers_module.md 获取详细构象体文档。

生成构象体:

# 生成 3D 构象体
mol_3d = dm.conformers.generate(
    mol,
    n_confs=50,           # 生成数量(如为 None 则自动)
    rms_cutoff=0.5,       # 过滤相似构象体(埃)
    minimize_energy=True,  # 使用 UFF 力场最小化
    method='ETKDGv3'      # 嵌入方法(推荐)
)

# 访问构象体
n_conformers = mol_3d.GetNumConformers()
conf = mol_3d.GetConformer(0)  # 获取第一个构象体
positions = conf.GetPositions()  # 原子坐标 Nx3 数组

构象体聚类:

# 通过 RMSD 聚类构象体
clusters = dm.conformers.cluster(
    mol_3d,
    rms_cutoff=1.0,
    centroids=False
)

# 获取代表构象体
centroids = dm.conformers.return_centroids(mol_3d, clusters)

SASA 计算:

# 计算溶剂可及表面积
sasa_values = dm.conformers.sasa(mol_3d, n_jobs=-1)

# 从构象体属性访问 SASA
conf = mol_3d.GetConformer(0)
sasa = conf.GetDoubleProp('rdkit_free_sasa')

9. 可视化

参考 references/descriptors_viz.md 获取可视化文档。

基本分子网格:

# 可视化分子
dm.viz.to_image(
    mols[:20],
    legends=[dm.to_smiles(m) for m in mols[:20]],
    n_cols=5,
    mol_size=(300, 300)
)

# 保存到文件
dm.viz.to_image(mols, outfile="molecules.png")

# 用于出版的 SVG
dm.viz.to_image(mols, outfile="molecules.svg", use_svg=True)

对齐可视化(用于 SAR 分析):

# 通过公共子结构对齐分子
dm.viz.to_image(
    similar_mols,
    align=True,  # 启用 MCS 对齐
    legends=activity_labels,
    n_cols=4
)

突出显示子结构:

# 突出显示特定原子和键
dm.viz.to_image(
    mol,
    highlight_atom=[0, 1, 2, 3],  # 原子索引
    highlight_bond=[0, 1, 2]      # 键索引
)

构象体可视化:

# 显示多个构象体
dm.viz.conformers(
    mol_3d,
    n_confs=10,
    align_conf=True,
    n_cols=3
)

10. 化学反应

参考 references/reactions_data.md 获取反应文档。

应用反应:

from rdkit.Chem import rdChemReactions

# 从 SMARTS 定义反应
rxn_smarts = '[C:1](=[O:2])[OH:3]>>[C:1](=[O:2])[Cl:3]'
rxn = rdChemReactions.ReactionFromSmarts(rxn_smarts)

# 应用于分子
reactant = dm.to_mol("CC(=O)O")  # 乙酸
product = dm.reactions.apply_reaction(
    rxn,
    (reactant,),
    sanitize=True
)

# 转换为 SMILES
product_smiles = dm.to_smiles(product)

批处理反应应用:

# 应用于库
products = []
for mol in reactant_mols:
    try:
        prod = dm.reactions.apply_reaction(rxn, (mol,))
        if prod is not None:
            products.append(prod)
    except Exception as e:
        print(f"反应失败: {e}")

并行化

Datamol 包含许多操作的内置并行化。使用 n_jobs 参数:

  • n_jobs=1: 顺序(无并行化)
  • n_jobs=-1: 使用所有可用 CPU 核心
  • n_jobs=4: 使用 4 个核心

支持并行化的函数:

  • dm.read_sdf(..., n_jobs=-1)
  • dm.descriptors.batch_compute_many_descriptors(..., n_jobs=-1)
  • dm.cluster_mols(..., n_jobs=-1)
  • dm.pdist(..., n_jobs=-1)
  • dm.conformers.sasa(..., n_jobs=-1)

进度条: 许多批处理操作支持 progress=True 参数。

常见工作流和模式

完整管道: 数据加载 → 过滤 → 分析

import datamol as dm
import pandas as pd

# 1. 加载分子
df = dm.read_sdf("compounds.sdf")

# 2. 标准化
df['mol'] = df['mol'].apply(lambda m: dm.standardize_mol(m) if m else None)
df = df[df['mol'].notna()]  # 移除失败分子

# 3. 计算描述符
desc_df = dm.descriptors.batch_compute_many_descriptors(
    df['mol'].tolist(),
    n_jobs=-1,
    progress=True
)

# 4. 按药物相似性过滤
druglike = (
    (desc_df['mw'] <= 500) &
    (desc_df['logp'] <= 5) &
    (desc_df['hbd'] <= 5) &
    (desc_df['hba'] <= 10)
)
filtered_df = df[druglike]

# 5. 聚类并选择多样子集
diverse_mols = dm.pick_diverse(
    filtered_df['mol'].tolist(),
    npick=100
)

# 6. 可视化结果
dm.viz.to_image(
    diverse_mols,
    legends=[dm.to_smiles(m) for m in diverse_mols],
    outfile="diverse_compounds.png",
    n_cols=10
)

结构-活性关系 (SAR) 分析

# 按骨架分组
scaffolds = [dm.to_scaffold_murcko(mol) for mol in mols]
scaffold_smiles = [dm.to_smiles(s) for s in scaffolds]

# 创建带有活性的 DataFrame
sar_df = pd.DataFrame({
    'mol': mols,
    'scaffold': scaffold_smiles,
    'activity': activities  # 用户提供的活性数据
})

# 分析每个骨架系列
for scaffold, group in sar_df.groupby('scaffold'):
    if len(group) >= 3:  # 需要多个示例
        print(f"
骨架: {scaffold}")
        print(f"计数: {len(group)}")
        print(f"活性范围: {group['activity'].min():.2f} - {group['activity'].max():.2f}")

        # 以活性为图例可视化
        dm.viz.to_image(
            group['mol'].tolist(),
            legends=[f"活性: {act:.2f}" for act in group['activity']],
            align=True  # 通过公共子结构对齐
        )

虚拟筛选管道

# 1. 为查询和库生成指纹
query_fps = [dm.to_fp(mol) for mol in query_actives]
library_fps = [dm.to_fp(mol) for mol in library_mols]

# 2. 计算相似性
from scipy.spatial.distance import cdist
import numpy as np

distances = dm.cdist(query_actives, library_mols, n_jobs=-1)

# 3. 查找最接近匹配(最小距离到任何查询)
min_distances = distances.min(axis=0)
similarities = 1 - min_distances  # 将距离转换为相似性

# 4. 排名并选择顶部命中
top_indices = np.argsort(similarities)[::-1][:100]  # 顶部 100
top_hits = [library_mols[i] for i in top_indices]
top_scores = [similarities[i] for i in top_indices]

# 5. 可视化命中
dm.viz.to_image(
    top_hits[:20],
    legends=[f"相似性: {score:.3f}" for score in top_scores[:20]],
    outfile="screening_hits.png"
)

参考文档

详细 API 文档,请咨询这些参考文件:

  • references/core_api.md: 核心命名空间函数(转换、标准化、指纹、聚类)
  • references/io_module.md: 文件 I/O 操作(读取/写入 SDF、CSV、Excel、远程文件)
  • references/conformers_module.md: 3D 构象体生成、聚类、SASA 计算
  • references/descriptors_viz.md: 分子描述符和可视化函数
  • references/fragments_scaffolds.md: 骨架提取、BRICS/RECAP 片段化
  • references/reactions_data.md: 化学反应和玩具数据集

最佳实践

  1. 始终标准化分子 从外部源:

    mol = dm.standardize_mol(mol, disconnect_metals=True, normalize=True, reionize=True)
    
  2. 检查 None 值 在分子解析后:

    mol = dm.to_mol(smiles)
    if mol is None:
        # 处理无效 SMILES
    
  3. 使用并行处理 对于大型数据集:

    result = dm.operation(..., n_jobs=-1, progress=True)
    
  4. 利用 fsspec 用于云存储:

    df = dm.read_sdf("s3://bucket/compounds.sdf")
    
  5. 使用适当指纹 用于相似性:

    • ECFP (Morgan): 通用目的,结构相似性
    • MACCS: 快速,较小特征空间
    • 原子对: 考虑原子对和距离
  6. 考虑规模限制:

    • Butina 聚类: ~1,000 个分子(完整距离矩阵)
    • 对于更大数据集: 使用多样性选择或分层方法
  7. 骨架分割用于机器学习: 确保通过骨架进行适当的训练/测试分离

  8. 对齐分子 当可视化 SAR 系列时

错误处理

# 安全分子创建
def safe_to_mol(smiles):
    try:
        mol = dm.to_mol(smiles)
        if mol is not None:
            mol = dm.standardize_mol(mol)
        return mol
    except Exception as e:
        print(f"处理 {smiles} 失败: {e}")
        return None

# 安全批处理
valid_mols = []
for smiles in smiles_list:
    mol = safe_to_mol(smiles)
    if mol is not None:
        valid_mols.append(mol)

与机器学习集成

# 特征生成
X = np.array([dm.to_fp(mol) for mol in mols])

# 或描述符
desc_df = dm.descriptors.batch_compute_many_descriptors(mols, n_jobs=-1)
X = desc_df.values

# 训练模型
from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor()
model.fit(X, y_target)

# 预测
predictions = model.predict(X_test)

故障排除

问题: 分子解析失败

  • 解决方案: 先使用 dm.standardize_smiles() 或尝试 dm.fix_mol()

问题: 聚类内存错误

  • 解决方案: 对于大型集合,使用 dm.pick_diverse() 而不是完整聚类

问题: 构象体生成缓慢

  • 解决方案: 减少 n_confs 或增加 rms_cutoff 以生成更少构象体

问题: 远程文件访问失败

  • 解决方案: 确保安装 fsspec 和适当云提供商库(s3fs、gcsfs 等)

其他资源