Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/genomicranges/GenomicRanges.py
Original file line number Diff line number Diff line change
Expand Up @@ -1006,13 +1006,13 @@ def to_pandas(self):
_rdf["seqnames"] = self.get_seqnames()
_rdf["strand"] = self.get_strand(as_type="list")

if self._names is not None:
_rdf.index = self._names

if self._mcols is not None:
if self._mcols.shape[1] > 0:
_rdf = pd.concat([_rdf, self._mcols.to_pandas()], axis=1)

if self._names is not None:
_rdf.index = self._names

return _rdf

@classmethod
Expand Down
27 changes: 27 additions & 0 deletions tests/test_gr_initialize_pandas.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pytest
from genomicranges import GenomicRanges
from biocframe import BiocFrame
from iranges import IRanges
from random import random
import pandas as pd

Expand Down Expand Up @@ -41,3 +42,29 @@ def test_from_pandas_should_fail():
)
with pytest.raises(Exception):
GenomicRanges.from_pandas(df_gr)


def test_to_pandas_with_names_and_mcols_is_positional():
# Regression test for a bug where to_pandas() set the index to `names`
# before concatenating `mcols`, whose index was still the default
# positional RangeIndex. pandas.concat(axis=1) then outer-joined on the
# two disjoint indices instead of binding columns positionally, doubling
# the row count and NaN-splitting every row.
ranges = IRanges(start=[0, 10, 20], width=[5, 5, 5])
mcols = BiocFrame({"gene_id": ["g1", "g2", "g3"], "gene_name": ["A", "B", "C"]})
gr = GenomicRanges(
seqnames=["1", "1", "1"],
ranges=ranges,
strand=["+", "+", "-"],
names=["g1", "g2", "g3"],
mcols=mcols,
)

df = gr.to_pandas()

assert df.shape == (3, 7)
assert list(df.index) == ["g1", "g2", "g3"]
assert df["gene_id"].notna().all()
assert df["seqnames"].notna().all()
assert list(df["gene_id"]) == ["g1", "g2", "g3"]
assert list(df["gene_name"]) == ["A", "B", "C"]
Loading