如何使用Biopandas保存PDB文件?

人工智能 2026-07-09

我有一个经过处理的pdb文件,想进一步处理它并根据聚类算法的标签将其分成4 个不同的文件,这些标签保存在 'hlabs' 变量中。我的文件是 '1asy_pocket.pdb',可以用biopandas进行处理。然而,在构建了4 个不同的DataFrame之后,我无法将每个DataFrame保存到不同的文件中。

from biopandas.pdb import PandasPdb 
import pandas as pd
from distances import hlabs


pdb = PandasPdb().read_pdb('1asy_pocket.pdb')
print(pdb.df.keys())

atoms_df = pdb.df['ATOM']
hetatm_df = pdb.df['HETATM']

atoms = pd.concat([atoms_df, hetatm_df])
print(atoms)

series = pd.Series(hlabs, name="labels")
data = pd.concat([atoms, series], axis=1)
fragments = data.groupby(['labels'])

groups = []
names = []
for name, group in fragments:
    print(group.shape)
    group = pd.DataFrame(group)
    group = group.drop(['labels'], axis=1)
    groups.append(group)
    names.append(name)

numbers = range(0, len(groups))
numbers = list(map(str, numbers))
print(numbers)

for x, y in zip(groups, numbers):
    x.to_pdb(path='file'+y+'.pdb',
        records=['ATOM', 'HETATM'])

这里的问题在于,biopandas期望得到的不是一个dataframe (x),而是一个biopandas对象 pdb

 File "/hdda/mihai/first_model/pdb_test/april_test/pockets/./bpd.py", line 35, in <module>
    x.to_pdb(path='file'+y+'.pdb',
    ^^^^^^^^
  File "/hdda/mihai/miniconda/pytorch_env/lib/python3.13/site-packages/pandas/core/generic.py", line 6321, in __getattr__
    return object.__getattribute__(self, name)
           ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
AttributeError: 'DataFrame' object has no attribute 'to_pdb'. Did you mean: 'to_hdf'?

是否有可能把这4 个DataFrame转换成biopandas对象?

解决方案

看起来你必须为每个组创建一个新的对象 PandasPdb,并手动将 DataFrame 赋值给 df(或更确切地说赋值给 _df,如 源代码 所示)——大致像这样:

groups = []
names = []

for name, group in fragments:
    print(f"{group.shape=}")

    group = pd.DataFrame(group)  # I'm not sure if this is needed
    group = group.drop(["labels"], axis=1)

    new_pdb = PandasPdb()
    new_pdb._df["ATOM"] = group
    new_pdb._df["HETATM"] = hetatm_df  # it seems it is empty in original file

    groups.append(new_pdb)
    names.append(name)

顺便说一句:

你可以使用 enumerate() 代替 range()zip() 的组合。
你也可以使用 f-string,在文件名 f"file{index}.pdb" 中直接使用数字

for index, group in enumerate(groups):
    group.to_pdb(path=f"file{index}.pdb", records=["ATOM", "HETATM"])

你甚至可以用一个for循环来替代两个for循环

    # names = []

    for index, (name, group) in enumerate(fragments):
        print(f"{group.shape=}")

        group = pd.DataFrame(group)  # I'm not sure if this is needed
        group = group.drop(["labels"], axis=1)

        new_pdb = PandasPdb()
        new_pdb._df["ATOM"] = group
        new_pdb._df["HETATM"] = hetatm_df  # it seems it is empty in original file.

        new_pdb.to_pdb(path=f"file{index}.pdb", records=["ATOM", "HETATM"])

        # names.append(name)

用于测试的完整工作代码,示例文件
github.com/MIhaitrm/test/blob/master/1asy_pocket.pdb

我没有 distances.hlabs,所以用随机值创建了 hlabs

from biopandas.pdb import PandasPdb
import pandas as pd

# from distances import hlabs


def version_1():

    groups = []
    names = []

    for name, group in fragments:
        print(f"{group.shape=}")

        group = pd.DataFrame(group)  # I'm not sure if this is needed
        group = group.drop(["labels"], axis=1)

        new_pdb = PandasPdb()
        new_pdb._df["ATOM"] = group
        new_pdb._df["HETATM"] = hetatm_df  # it seems it is empty in original file.

        groups.append(new_pdb)
        names.append(name)

    # numbers = list(range(len(groups)))
    # print(numbers)

    for index, group in enumerate(groups):
        group.to_pdb(path=f"file{index}.pdb", records=["ATOM", "HETATM"])


def version_2():

    # names = []

    for index, (name, group) in enumerate(fragments):
        print(f"{group.shape=}")

        group = pd.DataFrame(group)  # I'm not sure if this is needed
        group = group.drop(["labels"], axis=1)

        new_pdb = PandasPdb()
        new_pdb._df["ATOM"] = group
        new_pdb._df["HETATM"] = hetatm_df  # it seems it is empty in original file.

        new_pdb.to_pdb(path=f"file{index}.pdb", records=["ATOM", "HETATM"])

        # names.append(name)


# --- main ---

pdb = PandasPdb().read_pdb("1asy_pocket.pdb")

print("--- pdb.df.keys() ---")
print(pdb.df.keys())

atoms_df = pdb.df["ATOM"]
hetatm_df = pdb.df["HETATM"]

print("--- atoms_df ---")
print(atoms_df)
print("--- hetatm_df ---")
print(hetatm_df)

atoms = pd.concat([atoms_df, hetatm_df])

print("--- atoms ---")
print(atoms)

# create random values in hlabs
import random

hlabs = random.choices(["A", "B", "C", "D"], k=len(atoms))

series = pd.Series(hlabs, name="labels")
data = pd.concat([atoms, series], axis=1)
fragments = data.groupby(["labels"])

version_1()
# version_2()
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章