多批次ADMET数据来源与格式归纳总结
接手过几套不同来源的ADMET数据后,我最大的体会是——数据长什么样,决定了你后续要花多少力气去洗。有的批次来自实验记录表,有的从公共数据库扒下来,还有的是从文献里一行一行手动摘的。格式五花八门,SMILES、SDF、CSV、JSON……光是看后缀就能让人头大。这一节咱们就把这些「来路」和「长相」理清楚。
数据来源:三大主流渠道
ADMET数据的来源,说白了就三种路数。我按自己踩过的坑排了个序,从最省心到最折腾。
| 来源类型 | 典型代表 | 数据量级 | 格式干净度 |
|---|---|---|---|
| 公开数据库 | ChEMBL、PubChem、DrugBank | 百万级 | ★★★★☆ 结构较规整 |
| 自建实验平台 | HTS筛选、ADMET assay平台 | 百到千级 | ★★★☆☆ 依赖实验记录规范 |
| 文献挖掘 | 论文补充材料、专利表格 | 几十到几百 | ★★☆☆☆ 碎片化、单位不一致 |
我的经验:虽然公开数据库下载很方便,但同一个化合物在不同库里的SMILES可能不一样,甚至手性标记都缺。我在整合ChEMBL和PubChem时就翻过车——看似相同的分子,标准化后才发现互变异构体没对齐。
数据格式:五种常见“壳”
不管你从哪拿数据,最终都会落到下面五种格式之一。我个人习惯把它们分成「结构化」和「半结构化」两类。
- CSV/TSV —— 最通用的表格格式,列标题通常为
SMILES, logD, pKa, HLM_Clint等。注意:SMILES列里可能有逗号或引号,要正确转义。 - SDF (Structure Data File) —— 化学信息学传统格式,每个分子有原子坐标 + 属性块。适合存三维结构,但属性值读取稍麻烦。
- JSON —— 现代API下载时常用,嵌套结构里可能混着数组和字典。比如
{"molecule": "CC(C)=O", "properties": {"logD": 0.8, "source": "PubChem"}}。 - XML —— 老派一些的数据库(如DrugBank)还在用,标签层级深,解析代码容易写长。
- 纯文本/SMILES列表 —— 文献里最常见,一个文件里一行一个SMILES,附一个数值。格式极简,但缺失元数据。
格式对比:一眼看出差异
| 格式 | 解析难度 | 属性承载能力 | 标准化推荐度 |
|---|---|---|---|
| CSV | ★☆☆☆☆ 简单 | 中等 | ★★★★★ 首选统一格式 |
| SDF | ★★★☆☆ 中等 | 高(含结构) | ★★★☆☆ 结构保留用 |
| JSON | ★★☆☆☆ 简单 | 高 | ★★★★☆ 程序友好 |
| XML | ★★★☆☆ 中等 | 高 | ★★☆☆☆ 近年来用得少 |
| 纯文本 | ★☆☆☆☆ 极简 | 极低 | ★★☆☆☆ 仅临时使用 |
避坑指南:我曾经拿到一个批次的数据,所有SMILES列都用双引号包裹,但双引号内部又出现了未转义的引号。结果pandas.read_csv直接崩了。解决办法是传
quoting=csv.QUOTE_ALL,或者指定 escapechar='\\'。
数据来源与格式的关系图
下面这张图梳理了常见数据源和它们输出的格式,以及我建议的标准化路径。你拿到新批次后,可以照着这个流程图快速定位。
核心原则:不管你拿到的原始格式多冷门,最终都归一成 CSV + 标准化SMILES。这一步做扎实了,后面所有脚本、模型、数据库入库才能统一处理。
实际操作:把SMILES标准化先做掉
拿到数据后第一件事不是看数值,而是检查SMILES。我踩过的坑里,至少有一半是因为SMILES没对齐导致重复或漏算。下面是个简单的标准化脚本片段,你可以放在数据预处理的第一步。
from rdkit import Chem
from rdkit.Chem import MolFromSmiles, MolToSmiles
def standardize_smiles(smiles):
mol = MolFromSmiles(smiles)
if mol is None:
return None
# 移除氢、标准化分子、生成canonical SMILES
mol = Chem.RemoveHs(mol)
return MolToSmiles(mol, canonical=True, isomericSmiles=False)
# 假设从CSV读取一行
raw_smiles = "C[C@@H](O)c1ccccc1"
std_smi = standardize_smiles(raw_smiles)
print(std_smi) # 输出:CC(O)c1ccccc1
上面的代码我用了很多次。注意 isomericSmiles=False 会把手性信息丢掉——如果你需要保留立体化学,改成 True。具体要不要丢,取决于你后期的建模需求。我一般在整合多批次时先统一走无手性版本,等需要立体异构体时再单独标记。
曾经踩过的坑:有一次跑完标准化后,发现两个批次的化合物数量加起来比预期少了15%。一查,原来其中一个批次使用“InChI”列而不是“SMILES”列,我漏掉了。务必在读取CSV前打印所有列名,或者写个函数自动识别。
格式这东西,你越早统一,后面越省心。我见过团队因为懒得标准化,最后不得不写一个「格式适配器」来对接五个不同来源的数据库——那代码量,够写半篇论文了。