跳转至

BioPandas 分子数据

一句话概述:BioPandas 把 PDB/mmCIF 等蛋白质结构文件读入 Pandas DataFrame,让你用 Pandas 的方式分析蛋白质 3D 结构数据,做距离计算、残基筛选、RMSD 计算等。

核心知识点

概念白话解释
PDB蛋白质数据库文件 = 存储蛋白质 3D 坐标的标准格式
mmCIF新格式 = PDB 的替代格式(支持更大的结构)
ATOM原子记录 = PDB 中每个原子的坐标信息
HETATM非标准原子 = 配体、水分子等非蛋白质原子
B-factor温度因子 = 原子位置的不确定性(值越大越灵活)
RMSD均方根偏差 = 两个结构之间的差异度量

安装配置

pip install biopandas                                # 安装 BioPandas
pip install pandas matplotlib                        # 依赖包

基本使用

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)                                 # 不压缩

常见报错

报错信息原因解决方法
FileNotFoundErrorPDB 文件路径错误检查文件路径
HTTPError 404PDB ID 不存在确认 PDB ID 是否正确
KeyError: 'ATOM'文件格式异常检查文件是否为标准 PDB
ValueError: alignmentRMSD 计算原子数不匹配确保两个结构的原子数一致

速查表

# === 读取 ===
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 年