218

Datamol:现代化学信息学数据处理工具

Datamol 在 RDKit 之上提供更简洁的 API 与并行处理,让分子数据清洗更顺手。这篇给出对比代码,说明它省掉了哪些样板。

Datamol 是 Valence Labs 开发的 RDKit 轻量封装。它不替代 RDKit,而是把日常最高频的操作——标准化、并行处理、批量转换——封装成更简洁、默认值更合理的 API。用过就会发现,它省掉的是那些每个项目都要重写一遍的样板代码

安装

pip install datamol
python -c "import datamol as dm; print(dm.__version__)"

同一件事:RDKit 与 Datamol 的写法对比

分子标准化在 RDKit 里要串好几步:

from rdkit import Chem
from rdkit.Chem.MolStandardize import rdMolStandardize

def standardize(smi):
    mol = Chem.MolFromSmiles(smi)
    if mol is None:
        return None
    mol = rdMolStandardize.Cleanup(mol)
    mol = rdMolStandardize.FragmentParent(mol)
    mol = rdMolStandardize.Uncharger().uncharge(mol)
    mol = rdMolStandardize.TautomerEnumerator().Canonicalize(mol)
    return Chem.MolToSmiles(mol)

Datamol 里是一行:

import datamol as dm

mol = dm.to_mol(smi, sanitize=True)
mol = dm.standardize_mol(mol, disconnect_metals=True, uncharge=True)
smi_clean = dm.to_smiles(mol)

# 或者直接对 SMILES
smi_clean = dm.standardize_smiles(smi)

并行处理是最大便利

import datamol as dm

smiles_list = df["smiles"].tolist()

# 自动并行 + 进度条 + 异常安全
mols = dm.parallelized(
    dm.to_mol, smiles_list,
    n_jobs=-1, progress=True, batch_size=1000,
)

# 批量算描述符,直接得到 DataFrame
desc = dm.descriptors.batch_compute_many_descriptors(
    [m for m in mols if m is not None], n_jobs=-1)
print(desc[["mw", "clogp", "tpsa", "qed", "sas", "n_rotatable_bonds"]].head())

dm.parallelized 处理了三件在 RDKit 里要自己写的事:进程池管理、进度显示、单个分子失败不中断整批。处理几十万分子时,这三点都很重要。

其它高频能力

功能 API
构象生成 dm.conformers.generate(mol, n_confs=10, align_conformers=True)
骨架提取 dm.to_scaffold_murcko(mol)
指纹 dm.to_fp(mol, fp_type="ecfp", radius=2)
相似性矩阵 dm.similarity.cdist(mols_a, mols_b)
聚类 dm.cluster_mols(mols, cutoff=0.7)
枚举互变异构 / 立体异构 dm.enumerate_tautomers / dm.enumerate_stereoisomers
读写多格式 dm.read_sdf / dm.read_csv / dm.to_sdf(支持远程路径)
绘图 dm.to_image(mols, legends=...)

一段典型的清洗管线

import datamol as dm
import pandas as pd

df = dm.read_csv("raw_library.csv")

def process(smi):
    mol = dm.to_mol(smi)
    if mol is None:
        return None
    mol = dm.standardize_mol(mol, disconnect_metals=True, uncharge=True)
    if mol is None or mol.GetNumHeavyAtoms() < 5:
        return None
    return dm.to_smiles(mol, canonical=True)

df["clean"] = dm.parallelized(process, df["smiles"], n_jobs=-1, progress=True)
df = df.dropna(subset=["clean"]).drop_duplicates(subset=["clean"])
print(f"保留 {len(df)} 个分子")

取舍

  • 优点:样板代码少、默认值合理、并行开箱即用、API 一致性好。做数据清洗和批量处理明显更顺手。
  • 代价:多一层依赖;封装意味着默认行为不一定符合你的需求,标准化这类关键步骤应该点进源码确认它到底做了什么。
  • 建议:用 Datamol 写日常管线,但要清楚每个封装背后对应的 RDKit 操作。学习阶段先掌握 RDKit,再用 Datamol 提效——反过来会导致对化学处理细节心里没底。

上手提示

  • 它的核心价值是省掉每个项目都要重写的样板;
  • dm.parallelized 自带并行、进度条与异常安全,是最实用的一个 API;
  • 标准化等关键步骤要确认默认行为,别盲信封装;
  • 先懂 RDKit 再用 Datamol,顺序反了会心里没底。

延伸资源