数据基础:药物数据来源与文件格式

做药物图谱分析,第一步就是搞明白数据从哪来、长什么样。我当年刚接触这个方向时,面对一堆陌生的数据库名字和格式,说实话有点懵。后来慢慢摸清楚了,其实核心就那么几个来源,格式也不复杂。

今天咱们就把这三个主流数据库——PubChem、DrugBank、ChEMBL,以及它们常用的文件格式——CSV、JSON、RDF,一次性捋清楚。

三大药物数据库,各有什么“脾气”

这三个库我都用过,各有各的侧重点。说白了,选哪个取决于你要分析什么。

数据库 维护方 侧重方向 数据量级 我最常用来
PubChem 美国国立卫生研究院(NCBI) 小分子化合物信息、生物活性、化学结构 1.2亿+化合物 批量下载化合物SMILES、InChI键
DrugBank 阿尔伯塔大学 已批准药物、药物靶点、药物-药物相互作用 ~1.3万药物条目 查找药物靶点关系和用药指南
ChEMBL 欧洲生物信息学研究所(EBI) 药物活性数据、ADMET性质、靶点结合亲和力 200万+生物活性测量值 构建定量构效关系模型

我个人的习惯是:做网络图谱时,DrugBank的“药物-靶点”关系最规整;做化学空间分析,PubChem的化合物覆盖更广;如果要深入活性数值,ChEMBL的Ki、IC50数据不可替代。

一点经验:千万别三个库同时全量下载。我曾经一次拉了全部数据,硬盘直接爆了。
建议按项目需求先下载特定子集,比如只下载“抗肿瘤药物”或者“作用于GPCR靶点的化合物”。

为什么这三个库格式不统一?嗯,历史原因。PubChem最早,用ASN.1起家后来推JSON;DrugBank早期是XML,现在全面拥抱RDF;ChEMBL则是关系型数据库底子,导出CSV最顺手。你想想看,做图谱整合时,这个格式差异就是第一个要跨的坎。

文件格式:三种“语言”怎么选

CSV、JSON、RDF,基本上覆盖了从轻量表格到语义网络的所有需求。

CSV:又快又糙,适合快速预览

我最开始就是从CSV入的门。简单打个比方:CSV就像一张Excel表格,每行一个记录,每列一个字段。在药物数据里,常见的CSV包含化合物ID、名称、SMILES、活性值等。

但要注意——CSV天生不带层级关系。一个药物如果对应多个靶点,CSV里要么重复行,要么用分隔符把靶点挤在一个单元格里。后者处理起来真的很麻烦。

# 一个典型的ChEMBL活性数据CSV片段
molregno,standard_value,standard_units,assay_type,target_chembl_id
CHEMBL1,10.5,nM,F,B,CHEMBL2345
CHEMBL2,220.0,nM,F,B,CHEMBL6789
CHEMBL2,5500.0,nM,F,B,CHEMBL1234

看到没?CHEMBL2出现了两行,因为同一个化合物测了两个靶点。

JSON:嵌套结构,很适合图谱构建

我个人觉得,JSON是现代数据分析的“通用语”。它天生支持嵌套,药物和靶点的多对多关系可以完美表达。PubChem的PC_Compound数据库就是JSON格式,里面有完整的化合物属性、同义词、计算性质等等。

{
  "CID": 2244,
  "IUPACName": "aspirin",
  "MolecularFormula": "C9H8O4",
  "MW": 180.16,
  "SMILES": "CC(=O)OC1=CC=CC=C1C(=O)O",
  "synonyms": ["acetylsalicylic acid", "ASA"]
}

在用Python做药物图谱时,我习惯先用json.load()把数据读成字典,再用NetworkX的from_dict_of_lists一步建图。非常顺手。

避坑指南:PubChem的JSON有些字段是嵌套的“数组套对象”,解析时要留意路径。
比如record['props']每个元素里还有urn、value子对象,写解析时最好先打印一两条看看结构。

RDF:语义网络的“母语”

DrugBank和ChEMBL都支持RDF导出。RDF用“主体-谓词-客体”三元组描述关系,简直是知识图谱的天生格式。但说实话,RDF的文档和工具链对新手不太友好。我最早用SPARQL查数据时,写一条简单查询得试半天。

# DrugBank RDF片段(Turtle语法)
@prefix drugbank: <http://identifiers.org/drugbank/> .
@prefix dbo: <http://bio2rdf.org/drugbank_vocabulary:> .

drugbank:DB01050 dbo:target drugbank:BE0001234 ;
                dbo:name "Aspirin" ;
                dbo:cas-number "50-78-2" .

你看,这句RDF就在说:“DB01050(阿司匹林)的目标靶点蛋白是BE0001234”。每条三元组都是一种关系,所有三元组连起来就是你需要的药物图谱。

三种格式怎么选?我的决策清单

  1. 如果你只是做简单的统计或机器学习,CSV就够用了,用pandas读取就行。
  2. 如果要建关系图谱(节点带属性、边带类型),建议用JSON,结构灵活,Python原生支持。
  3. 如果你要整合多个来源的知识图谱,或者需要做跨越PubMed、DrugBank、GO等数据的推理查询,RDF是最优解。
  4. 记住一个小技巧:不论来源是什么,先下载一小份样本,验证结构和字段完整性,再全量下载。我曾经直接拉ChEMBL的RDF全量,结果SPARQL端点超时了三次……

一张图看懂三大来源与格式的脉络

下面这张SVG图把这些关系画出来了,方便你快速记忆。

药物数据来源与文件格式脉络 PubChem 美国NCBI维护 DrugBank 加拿大阿尔伯塔大学 ChEMBL 欧洲EBI CSV JSON RDF 表格分析(Pandas) 知识图谱(NetworkX) 语义推理(SPARQL) 任何来源的原始数据,都不能直接用于图谱分析。 需要先解析、清洗、标准化,再构建节点和边。
我自己的代码流程:一般先用Python的csv或pandas读CSV,用json解析JSON。遇到RDF时,我会用rdflib库,把三元组转成DataFrame,再映射成图谱。
你不需要一次性掌握所有格式,先从CSV和JSON切入,RDF等你真正需要跨库推理时再学。

实际操作:拿一份PubChem JSON来练手

说了这么多,不如上手试试。下面是我从PubChem的API拉取阿司匹林信息的代码,返回的就是JSON。你看完就知道JSON结构多适合图谱了。

import requests, json
url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/2244/JSON"
resp = requests.get(url)
data = resp.json()
print(data['PC_Compounds'][0]['props'][0]['urn']['label'])

打印出来的是Molecular Weight。逐层点进去,你会发现每个属性都有明确的路径,直接就能作为图节点的属性字段。

注意:PubChem的API有调用频率限制,免费用户每秒最多5次请求。大规模下载建议用FTP批量获取。
我曾经在写教程时忘了加time.sleep(0.2),结果IP被临时封了半小时……嗯,尴尬。

从CSV到JSON再到RDF,格式越来越“重”,但表达关系的能力也越来越强。做药物图谱分析,我建议大家至少掌握CSV和JSON,RDF根据项目需要再深入。这个基础打好了,后面画图、做交互、整合外部数据都会顺手很多。