Skip to content

Commit d3bc372

Browse files
authored
BUG: pd.api.interchange.from_pandas raises with all-null categorical (#53078)
Co-authored-by: MarcoGorelli <>
1 parent 4f4184d commit d3bc372

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

doc/source/whatsnew/v2.0.2.rst

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Fixed regressions
2121

2222
Bug fixes
2323
~~~~~~~~~
24+
- Bug in :func:`api.interchange.from_dataframe` was raising ``IndexError`` on empty categorical data (:issue:`53077`)
2425
- Bug in :func:`api.interchange.from_dataframe` was returning :class:`DataFrame`'s of incorrect sizes when called on slices (:issue:`52824`)
2526
- Bug in :func:`api.interchange.from_dataframe` was unnecessarily raising on bitmasks (:issue:`49888`)
2627
- Bug in :func:`to_timedelta` was raising ``ValueError`` with ``pandas.NA`` (:issue:`52909`)

pandas/core/interchange/from_dataframe.py

+4-1
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

+12
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)