Skip to content

Commit 1bb9365

Browse files
Backport PR pandas-dev#53078 on branch 2.0.x (BUG: pd.api.interchange.from_pandas raises with all-null categorical) (pandas-dev#53081)
Backport PR pandas-dev#53078: BUG: pd.api.interchange.from_pandas raises with all-null categorical Co-authored-by: Marco Edward Gorelli <[email protected]>
1 parent 9135c3a commit 1bb9365

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

doc/source/whatsnew/v2.0.2.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Fixed regressions
2020

2121
Bug fixes
2222
~~~~~~~~~
23+
- Bug in :func:`api.interchange.from_dataframe` was raising ``IndexError`` on empty categorical data (:issue:`53077`)
2324
- Bug in :func:`api.interchange.from_dataframe` was returning :class:`DataFrame`'s of incorrect sizes when called on slices (:issue:`52824`)
2425
- Bug in :func:`api.interchange.from_dataframe` was unnecessarily raising on bitmasks (:issue:`49888`)
2526
- Bug in :meth:`DataFrame.convert_dtypes` ignores ``convert_*`` keywords when set to False ``dtype_backend="pyarrow"`` (:issue:`52872`)

pandas/core/interchange/from_dataframe.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,10 @@ def categorical_column_to_series(col: Column) -> tuple[pd.Series, Any]:
202202

203203
# Doing module in order to not get ``IndexError`` for
204204
# out-of-bounds sentinel values in `codes`
205-
values = categories[codes % len(categories)]
205+
if len(categories) > 0:
206+
values = categories[codes % len(categories)]
207+
else:
208+
values = codes
206209

207210
cat = pd.Categorical(
208211
values, categories=categories, ordered=categorical["is_ordered"]

pandas/tests/interchange/test_impl.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,18 @@ def test_categorical_pyarrow():
8989
tm.assert_frame_equal(result, expected)
9090

9191

92+
def test_empty_categorical_pyarrow():
93+
# https://github.com/pandas-dev/pandas/issues/53077
94+
pa = pytest.importorskip("pyarrow", "11.0.0")
95+
96+
arr = [None]
97+
table = pa.table({"arr": pa.array(arr, "float64").dictionary_encode()})
98+
exchange_df = table.__dataframe__()
99+
result = pd.api.interchange.from_dataframe(exchange_df)
100+
expected = pd.DataFrame({"arr": pd.Categorical([np.nan])})
101+
tm.assert_frame_equal(result, expected)
102+
103+
92104
def test_large_string_pyarrow():
93105
# GH 52795
94106
pa = pytest.importorskip("pyarrow", "11.0.0")

0 commit comments

Comments
 (0)