在药物发现和生物医学研究中,DrugBank数据库作为权威的药物信息资源库,包含了大量药物分子、靶点、相互作用等关键数据。然而,当科研人员尝试复现相关论文时,常常面临原始数据处理代码难以理解的困境。本文将深入解析一个典型的DrugBank数据处理GitHub项目,提供从环境配置到代码解读的完整指南,帮助研究者快速掌握数据处理技巧。
DrugBank采用严格的访问控制政策,需要完成以下步骤获取数据:
提示:申请时建议详细说明研究目的,使用机构邮箱能显著提高通过率。时差因素可能导致回复延迟,建议在工作日发送申请。
推荐使用conda创建独立Python环境:
bash复制conda create -n drugbank python=3.8
conda activate drugbank
pip install pandas lxml tqdm requests
关键工具版本要求:
以典型项目DESC_MOL-DDIE为例,其核心结构如下:
code复制database/
├── raw/ # 原始数据
├── processed/ # 处理后的数据
├── scripts/
│ ├── get_dict.py # 核心数据处理脚本
│ └── preprocess.sh # 自动化处理流程
└── README.md # 项目说明
下载的DrugBank数据通常为XML格式,文件结构示例如下:
xml复制<drugbank>
<drug type="biotech" created="2005-06-13">
<drugbank-id primary="true">DB00001</drugbank-id>
<name>Lepirudin</name>
<description>重组水蛭素类似物...</description>
<targets>
<target>
<name>Prothrombin</name>
</target>
</targets>
</drug>
</drugbank>
该脚本主要完成药物特征提取和字典构建:
python复制def parse_drug(drug_node):
"""解析单个药物节点"""
drug_dict = {
'db_id': drug_node.find('drugbank-id').text,
'name': drug_node.find('name').text,
'smiles': get_smiles(drug_node),
'targets': [t.text for t in drug_node.iterfind('targets/target/name')]
}
return drug_dict
def get_smiles(node):
"""提取SMILES化学表示"""
for prop in node.iterfind('calculated-properties/property'):
if prop.find('kind').text == 'SMILES':
return prop.find('value').text
return None
preprocess.sh实现端到端处理:
bash复制#!/bin/bash
# 解压原始数据
unzip -o drugbank_all.xml.zip
# 执行Python处理脚本
python scripts/get_dict.py \
--input drugbank_all.xml \
--output processed/drug_dict.pkl
# 生成精简数据集
head -n 1000 processed/drug_dict.pkl > sample.pkl
对于大文件处理,可采用流式解析:
python复制from lxml import etree
context = etree.iterparse('drugbank_all.xml', events=('end',), tag='drug')
for event, elem in context:
process_drug(elem) # 自定义处理函数
elem.clear() # 及时释放内存
建议使用防御性编程:
python复制def safe_extract(node, path, default=None):
elem = node.find(path)
return elem.text if elem is not None else default
python复制from multiprocessing import Pool
with Pool(processes=4) as pool:
results = pool.map(parse_drug, drug_nodes)
处理完成后应验证数据完整性:
python复制import pickle
with open('drug_dict.pkl', 'rb') as f:
data = pickle.load(f)
print(f"药物数量: {len(data)}")
print(f"示例条目: {list(data.values())[0]}")
处理后的数据可用于:
对于需要调试的情况,建议先从单个药物样本入手:
python复制sample_drug = next(iter(data.values()))
print(sample_drug['smiles'])