BioPandas: parsing PDB and MOL2 files into pandas DataFrames
Working with molecular structures in pandas DataFrames
At a glance
- What is it?
- A Python library that reads molecular structure files and hands you one DataFrame per record type, so structural biology data can be queried with the tools you already use for tabular data. It suits computational biologists who live in pandas and are tired of hand-parsing PDB columns.
- Who is it for?
- Adopt BioPandas if your pipeline already works in pandas and you need to read, filter or compare PDB and MOL2 structure files without writing a fixed-width parser. Do not adopt it for large structure collections or for workflows that need proper 3D geometry, since a DataFrame is a table, not a molecular object.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem is the fixed-width record, not the science
The project starts from a familiar complaint. If you are a computational biologist, chances are that you cursed one too many times about protein structure files, in the format of the Protein Data Bank, called PDB files. The format itself is not at fault. As the project puts it, PDB is a neatly structured format if deployed correctly, yet it is a bit cumbersome to work with PDB files in modern programming languages.
The awkwardness is concrete. A PDB file is a set of fixed-width records, and each record type, atoms, headers, hetatm entries, models and so on, has its own column layout. Pulling one field out of a line means counting character offsets, and the code that does it does not compose with anything else you have written.
BioPandas takes the pandas DataFrame as the interface for that data. The pitch is straightforward: why not take pandas to the structural biology world. Working with molecular structures of biological macromolecules, from PDB and MOL2 files, in pandas DataFrames is the whole scope of the library.
The audience is defined by that choice. This is for people whose mental model is already a dataframe, who would rather filter and aggregate than hand-roll parsers, and who want structure data to sit in the same pipeline as everything else they analyse.
One DataFrame per record type, with a fetch helper
The API surface is built around a single class, PandasPdb, and a dictionary of DataFrames behind it. Each record type in the file becomes its own frame, and the example in the project documentation shows the naming convention:
>>> from biopandas.pdb import PandasPdb
>>> ppdb = PandasPdb().fetch_pdb('3eiy')
>>> ppdb.df['ATOM'].head()The df attribute is the dictionary, and 'ATOM' is one of its keys. The fetch_pdb method pulls the file from rcsb.org as part of constructing the object, so a structure identifier is enough to get a populated object.
That structure is the design decision worth understanding. You do not get one big table with a mixed-type record column. You get a dict of homogeneous frames, one per record type, and you select the frame you care about by key. That means the usual pandas complaints about mixed types largely disappear, and the cost is that operations spanning record types, for example joining a ligand record back to its protein atoms, become explicit joins you write rather than operations the library does for you.
The class also separates the parsing step from the analysis step. Once the object exists, its frames are ordinary DataFrames, and everything you know about pandas applies to them.
RMSD between two structures, filtered by record and element
The second documented example shows the kind of task the library exists to make short. Two docking poses are read from disk and compared:
>>> pl1 = PandasPdb().read_pdb('./docking_pose_1.pdb')
>>> pl2 = PandasPdb().read_pdb('./docking_pose_2.pdb')
>>> r = PandasPdb.rmsd(pl1.df['HETATM'], pl2.df['HETATM'],
s='hydrogen', invert=True)Three things are worth noting in those three lines. read_pdb takes a local path, so the same class handles files you already have, not just fetched ones. The comparison operates on a single record type, here the HETATM frames, so you choose the subset of atoms you want to align before any geometry happens. And the s parameter selects which element to use for the calculation, with invert=True flipping the sense of the selection.
The point of the example is that you select and filter with pandas before the structural maths runs. The element choice is a filter on the frame you pass in, and the record type is a key lookup in a dictionary. The library does not need a domain object model to give you a structure comparison; it needs the right rows.
The documentation prints the result of that call, so you can see the expected shape of the output rather than only the call that produces it.
Installing it, and the dependency floors that disagree
There are three documented installation routes. The PyPI route is the shortest:
pip install biopandasThe conda-forge route is:
conda install biopandas -c conda-forgeAnd the GitHub route, which the documentation labels as installing the latest version from GitHub, uses a git URL with an egg fragment:
pip install git+git://github.com/rasbt/biopandas.git#egg=biopandasNote that the git URL points at the rasbt organisation rather than the BioPandas organisation that now holds the repository, so a fork-and-reinstall workflow under a different name needs the URL edited.
The requirements are where the documentation stops being tidy. The README lists Python 3.7 or later, NumPy 1.11.2 or later, SciPy 0.18.1 or later, and Pandas 0.19.1 or later. The requirements.txt in the repository root lists something different:
numpy>=1.16.2
pandas>=0.24.2
mmtf-python==1.1.3
looseversion==1.1.2Two floors are stricter in the file than in the README, SciPy does not appear in the file at all, and two pinned dependencies appear only in the file. mmtf-python is the reader for the MMTF binary structure format, and the pin is exact. Whatever your environment already has, install into a fresh virtual environment and read the resolved dependency list rather than trusting the README table.
The setup.py script reads the version out of biopandas/__init__.py at build time and takes install requirements from requirements.txt, so the file is the version that governs what pip actually installs.
Where a DataFrame stops being the right shape
There is a category of task this design deliberately does not cover, and it is worth naming before you commit.
A PDB file encodes three-dimensional geometry: coordinates, bonds implied by residue templates, chirality, and a sequence whose meaning depends on the residue types and their arrangement. A DataFrame is a table of values, and a value such as an x coordinate has no notion of a neighbour. So any analysis that depends on topology, on spatial adjacency, on the chemical identity of a residue rather than its label, has to be reconstructed from the table by your own code.
The library also does not claim to be a general structure file reader. The scope named in the project is PDB and MOL2 files, with the dependency list pointing at the MMTF format as well. Formats outside that set are not handled, and the documentation available here does not describe error handling for malformed or unusual files.
The practical symptom is that you will reach for a table library and then find yourself writing neighbour searches by hand. That is a reasonable trade for filtering, grouping and tabular comparisons, and a poor one for anything that treats the structure as a graph.
Against writing the parser yourself, or against a structure library
Two comparisons are honest here.
The first is against hand-written parsing. Fixed-width parsing is a solved but tedious problem, and the value of a dedicated library is not the parser itself but the record type split. Once you have it, selecting atoms of a given element or residue is a boolean mask on a frame rather than a loop over lines. The cost of adopting the library is the dependency set, including the exact pins in requirements.txt, and the fact that your structure data now lives in a pandas world where index alignment and dtype surprises are part of the deal.
The second is against a molecular modelling library. Tools built around actual molecular objects model the structure: they keep residue identity, keep bonds, expose spatial queries, and can compute physical properties. They also give you a dataframe only if you write the conversion. BioPandas goes the other way. It gives you the table immediately and leaves the modelling to you.
So the deciding question is which side of that line your work sits on. If your pipeline needs to slice, count, group and compare records, BioPandas removes the parsing tax. If it needs to reason about the structure itself, the alternative with real molecular objects is the right starting point and BioPandas is a preprocessing step in front of it, not a replacement.
A library with a JOSS paper, an active tree, and a stale README
BioPandas carries a citation request, which is unusual and useful for research software. If you use it as part of a workflow in a scientific publication, the project asks you to cite the repository with a DOI, and gives the reference to Sebastian Raschka, Biopandas: Working with molecular structures in pandas dataframes, The Journal of Open Source Software, 2(14), June 2017, with doi 10.21105/joss.00279. The paper source is in the repository as paper.md, paper.bib and paper.pdf.
The licence is BSD 3-Clause, recorded in LICENSE.txt and in the setup.py metadata. The classifiers in setup.py list BSD under OSI approved licences and mark the development status as 5 Production/Stable, while also listing Python 3.5 through 3.8 among the supported versions, which is a detail from an earlier era of the project.
The repository is not archived and the last push was on 2026-10-17. Released versions tell a slower story: v0.5.2 was published on 2026-08-24, v0.5.1 on 2024-08-01, and a v0.5.1dev build on 2023-08-28. So the code is being worked on, but the version cadence is irregular, and the documentation you read online may describe requirements that the current requirements.txt has already moved past. That is the practical upgrade cost: check the pinned versions in requirements.txt after every pull, and read the changelog at docs/sources/CHANGELOG.md before moving across versions.
Editorial conclusion
Adopt BioPandas if your pipeline already works in pandas and you need to read, filter or compare PDB and MOL2 structure files without writing a fixed-width parser. Do not adopt it for large structure collections or for workflows that need proper 3D geometry, since a DataFrame is a table, not a molecular object. Before you rely on it, check the dependency floors, since the README lists pandas 0.19.1 while requirements.txt asks for pandas 0.24.2, and confirm your structure file parses into the record type you expect rather than assuming a uniform table.
Frequently asked questions
How do I install BioPandas?
The documented routes are pip install biopandas for the PyPI version, conda install biopandas -c conda-forge for conda-forge, and a git URL install for the latest version from GitHub. The README points to the installation page of the project documentation for more detail.
What does a BioPandas PandasPdb object give me?
It gives you a df attribute holding a dictionary of DataFrames, one per record type, so you can select a frame by key such as ppdb.df['ATOM']. Files can be fetched with fetch_pdb or read from disk with read_pdb.
How do I compute RMSD between two structures with BioPandas?
Read both structures, pass the frames you want to compare to the rmsd method, and use the s parameter to pick the element used for the calculation, with invert=True flipping the selection. The documentation example compares the HETATM frames of two docking poses.
Which structure formats does BioPandas support?
The stated scope is molecular structures of biological macromolecules from PDB and MOL2 files. The dependency list in requirements.txt also includes mmtf-python, the reader for the MMTF binary format.
What are the dependencies for BioPandas?
The README lists Python 3.7 or later, NumPy 1.11.2 or later, SciPy 0.18.1 or later and Pandas 0.19.1 or later. The requirements.txt file in the repository root is stricter on some of these and adds mmtf-python and looseversion.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/biopandas-biopandas)