Skip to content

Commit 3bbaa89

Browse files
authored
BUG: Series[object].fillna ignoring downcast='infer' (#45062)
1 parent 5606684 commit 3bbaa89

File tree

4 files changed

+47
-4
lines changed

4 files changed

+47
-4
lines changed

doc/source/whatsnew/v1.4.0.rst

+2
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,8 @@ Missing
734734
- Bug in :meth:`Series.interpolate` and :meth:`DataFrame.interpolate` with ``inplace=True`` not writing to the underlying array(s) in-place (:issue:`44749`)
735735
- Bug in :meth:`Index.fillna` incorrectly returning an un-filled :class:`Index` when NA values are present and ``downcast`` argument is specified. This now raises ``NotImplementedError`` instead; do not pass ``downcast`` argument (:issue:`44873`)
736736
- Bug in :meth:`DataFrame.dropna` changing :class:`Index` even if no entries were dropped (:issue:`41965`)
737+
- Bug in :meth:`Series.fillna` with an object-dtype incorrectly ignoring ``downcast="infer"`` (:issue:`44241`)
738+
-
737739

738740
MultiIndex
739741
^^^^^^^^^^

pandas/core/generic.py

+5
Original file line numberDiff line numberDiff line change
@@ -6399,6 +6399,11 @@ def fillna(
63996399
else:
64006400
if self.ndim == 1:
64016401
if isinstance(value, (dict, ABCSeries)):
6402+
if not len(value):
6403+
# test_fillna_nonscalar
6404+
if inplace:
6405+
return None
6406+
return self.copy()
64026407
value = create_series_with_explicit_dtype(
64036408
value, dtype_if_empty=object
64046409
)

pandas/core/internals/blocks.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -518,11 +518,11 @@ def split_and_operate(self, func, *args, **kwargs) -> list[Block]:
518518
def _maybe_downcast(self, blocks: list[Block], downcast=None) -> list[Block]:
519519

520520
if self.dtype == _dtype_obj:
521-
# TODO: why is behavior different for object dtype?
522-
if downcast is not None:
523-
return blocks
524-
521+
# GH#44241 We downcast regardless of the argument;
522+
# respecting 'downcast=None' may be worthwhile at some point,
523+
# but ATM it breaks too much existing code.
525524
# split and convert the blocks
525+
526526
return extend_blocks(
527527
[blk.convert(datetime=True, numeric=False) for blk in blocks]
528528
)

pandas/tests/series/methods/test_fillna.py

+36
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,42 @@ def test_fillna_downcast(self):
189189
expected = Series([1, 0])
190190
tm.assert_series_equal(result, expected)
191191

192+
def test_fillna_downcast_infer_objects_to_numeric(self):
193+
# GH#44241 if we have object-dtype, 'downcast="infer"' should
194+
# _actually_ infer
195+
196+
arr = np.arange(5).astype(object)
197+
arr[3] = np.nan
198+
199+
ser = Series(arr)
200+
201+
res = ser.fillna(3, downcast="infer")
202+
expected = Series(np.arange(5), dtype=np.int64)
203+
tm.assert_series_equal(res, expected)
204+
205+
res = ser.ffill(downcast="infer")
206+
expected = Series([0, 1, 2, 2, 4], dtype=np.int64)
207+
tm.assert_series_equal(res, expected)
208+
209+
res = ser.bfill(downcast="infer")
210+
expected = Series([0, 1, 2, 4, 4], dtype=np.int64)
211+
tm.assert_series_equal(res, expected)
212+
213+
# with a non-round float present, we will downcast to float64
214+
ser[2] = 2.5
215+
216+
expected = Series([0, 1, 2.5, 3, 4], dtype=np.float64)
217+
res = ser.fillna(3, downcast="infer")
218+
tm.assert_series_equal(res, expected)
219+
220+
res = ser.ffill(downcast="infer")
221+
expected = Series([0, 1, 2.5, 2.5, 4], dtype=np.float64)
222+
tm.assert_series_equal(res, expected)
223+
224+
res = ser.bfill(downcast="infer")
225+
expected = Series([0, 1, 2.5, 4, 4], dtype=np.float64)
226+
tm.assert_series_equal(res, expected)
227+
192228
def test_timedelta_fillna(self, frame_or_series):
193229
# GH#3371
194230
ser = Series(

0 commit comments

Comments
 (0)