使用Python的cElementTree提取DrugBank XML数据的方法问询
嘿,我之前刚好处理过DrugBank的XML数据集,用Python的cElementTree(在Python3里其实已经整合到xml.etree.ElementTree中了,性能一样出色)提取数据核心要注意命名空间这个容易踩的坑——你的XML里带了xmlns="http://www.drugbank.ca",直接用标签名查找会找不到元素的。下面给你一步步拆解实现:
第一步:导入模块并解析XML
首先导入对应的模块,然后加载你的XML文件:
# Python2用这个,Python3也兼容,或者直接import xml.etree.ElementTree as ET import xml.etree.cElementTree as ET # 解析XML文件 tree = ET.parse('你的drugbank文件名.xml') root = tree.getroot()
第二步:处理命名空间
因为所有元素都属于http://www.drugbank.ca这个命名空间,我们需要定义一个命名空间映射,这样查找元素时更清晰:
# 定义命名空间别名,方便后续查找 ns = {'db': 'http://www.drugbank.ca'}
第三步:提取基础数据示例
比如遍历所有药物,提取它们的主ID、类型、创建和更新时间:
for drug in root.findall('db:drug', ns): # 获取drug标签的属性 drug_type = drug.get('type') created = drug.get('created') updated = drug.get('updated') # 找到primary为true的drugbank-id primary_id = None for db_id in drug.findall('db:drugbank-id', ns): if db_id.get('primary') == 'true': primary_id = db_id.text break # 找到主ID就停止遍历 print(f"主ID: {primary_id}, 类型: {drug_type}, 创建时间: {created}, 更新时间: {updated}")
第四步:提取特定药物的信息
如果要定位到某个具体药物(比如DB00001),可以这样做:
target_id = 'DB00001' target_drug = None for drug in root.findall('db:drug', ns): for db_id in drug.findall('db:drugbank-id', ns): if db_id.get('primary') == 'true' and db_id.text == target_id: target_drug = drug break if target_drug: break if target_drug: # 假设你要提取药物名称(XML里应该有<name>标签) drug_name = target_drug.find('db:name', ns).text print(f"找到目标药物: {drug_name} (ID: {target_id})") # 你可以继续提取其他标签,比如适应症、分子式等,方法都是用find/findall加命名空间
处理大XML文件的优化
如果你的DrugBank XML文件特别大(毕竟数据集不小),直接用parse会占用大量内存,建议用迭代解析的方式,边解析边处理,处理完就释放内存:
for event, elem in ET.iterparse('你的drugbank文件名.xml', events=('end',)): # 只处理</drug>标签结束的事件 if elem.tag == '{http://www.drugbank.ca}drug': # 提取主ID primary_id = None for db_id in elem.findall('{http://www.drugbank.ca}drugbank-id'): if db_id.get('primary') == 'true': primary_id = db_id.text break print(f"处理药物: {primary_id}") # 清理当前元素,释放内存 elem.clear() # 清理父节点的引用(可选,进一步节省内存) while elem.getprevious() is not None: del elem.getparent()[0]
最后提醒一下:所有元素查找都必须带上命名空间,不管是用find、findall还是迭代解析时的标签判断,否则会找不到任何元素哦!
内容的提问来源于stack exchange,提问作者Sparker0i
相关产品推荐
相关产品推荐

