55 lines
1.8 KiB
Python
55 lines
1.8 KiB
Python
|
import numpy as np
|
||
|
import pytest
|
||
|
|
||
|
from pandas import CategoricalIndex
|
||
|
import pandas._testing as tm
|
||
|
|
||
|
|
||
|
class TestFillNA:
|
||
|
def test_fillna_categorical(self):
|
||
|
# GH#11343
|
||
|
idx = CategoricalIndex([1.0, np.nan, 3.0, 1.0], name="x")
|
||
|
# fill by value in categories
|
||
|
exp = CategoricalIndex([1.0, 1.0, 3.0, 1.0], name="x")
|
||
|
tm.assert_index_equal(idx.fillna(1.0), exp)
|
||
|
|
||
|
cat = idx._data
|
||
|
|
||
|
# fill by value not in categories raises TypeError on EA, casts on CI
|
||
|
msg = "Cannot setitem on a Categorical with a new category"
|
||
|
with pytest.raises(TypeError, match=msg):
|
||
|
cat.fillna(2.0)
|
||
|
|
||
|
result = idx.fillna(2.0)
|
||
|
expected = idx.astype(object).fillna(2.0)
|
||
|
tm.assert_index_equal(result, expected)
|
||
|
|
||
|
def test_fillna_copies_with_no_nas(self):
|
||
|
# Nothing to fill, should still get a copy for the Categorical method,
|
||
|
# but OK to get a view on CategoricalIndex method
|
||
|
ci = CategoricalIndex([0, 1, 1])
|
||
|
result = ci.fillna(0)
|
||
|
assert result is not ci
|
||
|
assert tm.shares_memory(result, ci)
|
||
|
|
||
|
# But at the EA level we always get a copy.
|
||
|
cat = ci._data
|
||
|
result = cat.fillna(0)
|
||
|
assert result._ndarray is not cat._ndarray
|
||
|
assert result._ndarray.base is None
|
||
|
assert not tm.shares_memory(result, cat)
|
||
|
|
||
|
def test_fillna_validates_with_no_nas(self):
|
||
|
# We validate the fill value even if fillna is a no-op
|
||
|
ci = CategoricalIndex([2, 3, 3])
|
||
|
cat = ci._data
|
||
|
|
||
|
msg = "Cannot setitem on a Categorical with a new category"
|
||
|
res = ci.fillna(False)
|
||
|
# nothing to fill, so we dont cast
|
||
|
tm.assert_index_equal(res, ci)
|
||
|
|
||
|
# Same check directly on the Categorical
|
||
|
with pytest.raises(TypeError, match=msg):
|
||
|
cat.fillna(False)
|