BioPandas 分子数据¶
一句话概述:BioPandas 把 PDB/mmCIF 等蛋白质结构文件读入 Pandas DataFrame,让你用 Pandas 的方式分析蛋白质 3D 结构数据,做距离计算、残基筛选、RMSD 计算等。
核心知识点¶
| 概念 | 白话解释 |
|---|---|
| PDB | 蛋白质数据库文件 = 存储蛋白质 3D 坐标的标准格式 |
| mmCIF | 新格式 = PDB 的替代格式(支持更大的结构) |
| ATOM | 原子记录 = PDB 中每个原子的坐标信息 |
| HETATM | 非标准原子 = 配体、水分子等非蛋白质原子 |
| B-factor | 温度因子 = 原子位置的不确定性(值越大越灵活) |
| RMSD | 均方根偏差 = 两个结构之间的差异度量 |
安装配置¶
基本使用¶
from biopandas.pdb import PandasPdb # 导入 PDB 解析器
# 从文件读取
ppdb = PandasPdb().read_pdb('protein.pdb') # 读取本地文件
# 从 RCSB PDB 下载
ppdb = PandasPdb().fetch_pdb('3eiy') # 下载 PDB ID: 3EIY
# 查看数据结构
print(ppdb.df['ATOM'].head()) # 原子坐标表
print(ppdb.df['HETATM'].head()) # 非标准原子表
print(ppdb.df['ATOM'].columns.tolist()) # 列名列表
# 基本信息
atoms = ppdb.df['ATOM'] # 获取原子 DataFrame
print(f"原子数: {len(atoms)}") # 总原子数
print(f"残基数: {atoms['residue_number'].nunique()}") # 残基数
print(f"链数: {atoms['chain_id'].nunique()}") # 链数
# 筛选特定链
chain_a = atoms[atoms['chain_id'] == 'A'] # 只要 A 链
print(f"A 链原子数: {len(chain_a)}")
# 筛选特定残基
active_site = atoms[atoms['residue_number'].isin([145, 41, 166])] # 活性位点
print(active_site[['atom_name', 'residue_name', 'residue_number']])
# 筛选 CA 原子(α-碳)
ca_atoms = atoms[atoms['atom_name'] == 'CA'] # 只要 CA 原子
print(f"残基数(CA 计数): {len(ca_atoms)}")
距离计算¶
import numpy as np # 导入 NumPy
# 计算两个原子之间的距离
atom1 = atoms[(atoms['residue_number'] == 145) &
(atoms['atom_name'] == 'CA')] # 第145残基CA
atom2 = atoms[(atoms['residue_number'] == 41) &
(atoms['atom_name'] == 'CA')] # 第41残基CA
coord1 = atom1[['x_coord', 'y_coord', 'z_coord']].values[0] # 坐标1
coord2 = atom2[['x_coord', 'y_coord', 'z_coord']].values[0] # 坐标2
distance = np.linalg.norm(coord1 - coord2) # 欧几里得距离
print(f"距离: {distance:.2f} Å") # 打印距离
# 配体周围的残基(如 5Å 内)
ligand = ppdb.df['HETATM'] # 配体原子
ligand_center = ligand[['x_coord', 'y_coord', 'z_coord']].mean().values
atoms_coords = atoms[['x_coord', 'y_coord', 'z_coord']].values
distances = np.linalg.norm(atoms_coords - ligand_center, axis=1)
nearby = atoms[distances < 5.0] # 5Å 内的原子
print(f"配体附近残基: {nearby['residue_number'].unique()}")
高级用法¶
RMSD 计算¶
from biopandas.pdb import PandasPdb
# 比较两个结构
ppdb1 = PandasPdb().fetch_pdb('3eiy') # 结构1
ppdb2 = PandasPdb().fetch_pdb('4eiy') # 结构2
# 计算 RMSD(用 CA 原子)
rmsd = PandasPdb.rmsd(
ppdb1.df['ATOM'][ppdb1.df['ATOM']['atom_name'] == 'CA'],
ppdb2.df['ATOM'][ppdb2.df['ATOM']['atom_name'] == 'CA'],
s='x_coord', s2='y_coord', s3='z_coord'
)
print(f"RMSD: {rmsd:.2f} Å")
B-factor 分析与可视化¶
import matplotlib.pyplot as plt # 导入绑图库
ca_atoms = ppdb.df['ATOM'][ppdb.df['ATOM']['atom_name'] == 'CA']
plt.figure(figsize=(12, 4))
plt.plot(ca_atoms['residue_number'], ca_atoms['b_factor']) # B-factor 图
plt.xlabel('残基编号')
plt.ylabel('B-factor')
plt.title('B-factor 沿序列分布')
plt.savefig('bfactor_plot.png', dpi=300)
写入修改后的 PDB¶
# 修改 B-factor 列
ppdb.df['ATOM']['b_factor'] = 0.0 # 清零 B-factor
ppdb.to_pdb(path='modified.pdb', # 写入新文件
records=['ATOM', 'HETATM'], # 包含的记录类型
gz=False) # 不压缩
常见报错¶
| 报错信息 | 原因 | 解决方法 |
|---|---|---|
FileNotFoundError | PDB 文件路径错误 | 检查文件路径 |
HTTPError 404 | PDB ID 不存在 | 确认 PDB ID 是否正确 |
KeyError: 'ATOM' | 文件格式异常 | 检查文件是否为标准 PDB |
ValueError: alignment | RMSD 计算原子数不匹配 | 确保两个结构的原子数一致 |
速查表¶
# === 读取 ===
ppdb = PandasPdb().read_pdb('file.pdb') # 本地文件
ppdb = PandasPdb().fetch_pdb('3eiy') # RCSB 下载
# === 数据访问 ===
ppdb.df['ATOM'] # 原子 DataFrame
ppdb.df['HETATM'] # 配体 DataFrame
ppdb.df['ATOM']['x_coord'] # X 坐标列
# === 常用筛选 ===
df[df['chain_id'] == 'A'] # 按链筛选
df[df['atom_name'] == 'CA'] # 按原子名筛选
df[df['residue_name'] == 'ALA'] # 按残基名筛选
df[df['residue_number'].between(10, 50)] # 按残基编号范围
# === BioPandas vs MDAnalysis vs PyMOL ===
# BioPandas: 轻量,Pandas 风格,适合简单分析
# MDAnalysis: 功能全面,支持 MD 轨迹分析
# PyMOL: 3D 可视化,适合结构展示
参考:BioPandas 文档 | 更新于 2026 年