Skip to content

Commit 2b69700

Browse files
authored
DEPR: use_inf_as_na (#53494)
* DEPR: use_inf_as_na * troubleshoot doc * troubleshoot docbuild * troubleshoot doc * troubleshoot docs
1 parent 21a81e9 commit 2b69700

File tree

17 files changed

+135
-96
lines changed

17 files changed

+135
-96
lines changed

doc/source/user_guide/missing_data.rst

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@ detect this value with data of different types: floating point, integer,
2929
boolean, and general object. In many cases, however, the Python ``None`` will
3030
arise and we wish to also consider that "missing" or "not available" or "NA".
3131

32-
.. note::
33-
34-
If you want to consider ``inf`` and ``-inf`` to be "NA" in computations,
35-
you can set ``pandas.options.mode.use_inf_as_na = True``.
36-
3732
.. _missing.isna:
3833

3934
.. ipython:: python

doc/source/whatsnew/v2.1.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ Deprecations
275275
- Deprecated allowing arbitrary ``fill_value`` in :class:`SparseDtype`, in a future version the ``fill_value`` will need to be compatible with the ``dtype.subtype``, either a scalar that can be held by that subtype or ``NaN`` for integer or bool subtypes (:issue:`23124`)
276276
- Deprecated behavior of :func:`assert_series_equal` and :func:`assert_frame_equal` considering NA-like values (e.g. ``NaN`` vs ``None`` as equivalent) (:issue:`52081`)
277277
- Deprecated constructing :class:`SparseArray` from scalar data, pass a sequence instead (:issue:`53039`)
278+
- Deprecated option "mode.use_inf_as_na", convert inf entries to ``NaN`` before instead (:issue:`51684`)
278279
- Deprecated positional indexing on :class:`Series` with :meth:`Series.__getitem__` and :meth:`Series.__setitem__`, in a future version ``ser[item]`` will *always* interpret ``item`` as a label, not a position (:issue:`50617`)
279280

280281
.. ---------------------------------------------------------------------------

pandas/_config/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ def __init__(self, *args) -> None:
438438
self.ops = list(zip(args[::2], args[1::2]))
439439

440440
def __enter__(self) -> None:
441-
self.undo = [(pat, _get_option(pat, silent=True)) for pat, val in self.ops]
441+
self.undo = [(pat, _get_option(pat)) for pat, val in self.ops]
442442

443443
for pat, val in self.ops:
444444
_set_option(pat, val, silent=True)

pandas/core/config_init.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,8 @@ def is_terminal() -> bool:
411411
True means treat None, NaN, INF, -INF as NA (old way),
412412
False means None and NaN are null, but INF, -INF are not NA
413413
(new way).
414+
415+
This option is deprecated in pandas 2.1.0 and will be removed in 3.0.
414416
"""
415417

416418
# We don't want to start importing everything at the global context level
@@ -426,6 +428,12 @@ def use_inf_as_na_cb(key) -> None:
426428
with cf.config_prefix("mode"):
427429
cf.register_option("use_inf_as_na", False, use_inf_as_na_doc, cb=use_inf_as_na_cb)
428430

431+
cf.deprecate_option(
432+
# GH#51684
433+
"mode.use_inf_as_na",
434+
"use_inf_as_na option is deprecated and will be removed in a future "
435+
"version. Convert inf values to NaN before operating instead.",
436+
)
429437

430438
data_manager_doc = """
431439
: string

pandas/core/frame.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10740,8 +10740,7 @@ def count(self, axis: Axis = 0, numeric_only: bool = False):
1074010740
"""
1074110741
Count non-NA cells for each column or row.
1074210742
10743-
The values `None`, `NaN`, `NaT`, and optionally `numpy.inf` (depending
10744-
on `pandas.options.mode.use_inf_as_na`) are considered NA.
10743+
The values `None`, `NaN`, `NaT`, ``pandas.NA`` are considered NA.
1074510744
1074610745
Parameters
1074710746
----------

pandas/core/indexes/base.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2820,8 +2820,7 @@ def isna(self) -> npt.NDArray[np.bool_]:
28202820
NA values, such as ``None``, :attr:`numpy.NaN` or :attr:`pd.NaT`, get
28212821
mapped to ``True`` values.
28222822
Everything else get mapped to ``False`` values. Characters such as
2823-
empty strings `''` or :attr:`numpy.inf` are not considered NA values
2824-
(unless you set ``pandas.options.mode.use_inf_as_na = True``).
2823+
empty strings `''` or :attr:`numpy.inf` are not considered NA values.
28252824
28262825
Returns
28272826
-------
@@ -2876,8 +2875,7 @@ def notna(self) -> npt.NDArray[np.bool_]:
28762875
28772876
Return a boolean same-sized object indicating if the values are not NA.
28782877
Non-missing values get mapped to ``True``. Characters such as empty
2879-
strings ``''`` or :attr:`numpy.inf` are not considered NA values
2880-
(unless you set ``pandas.options.mode.use_inf_as_na = True``).
2878+
strings ``''`` or :attr:`numpy.inf` are not considered NA values.
28812879
NA values, such as None or :attr:`numpy.NaN`, get mapped to ``False``
28822880
values.
28832881

pandas/tests/arrays/categorical/test_missing.py

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -137,18 +137,20 @@ def test_fillna_array(self):
137137
)
138138
def test_use_inf_as_na(self, values, expected):
139139
# https://github.com/pandas-dev/pandas/issues/33594
140-
with pd.option_context("mode.use_inf_as_na", True):
141-
cat = Categorical(values)
142-
result = cat.isna()
143-
tm.assert_numpy_array_equal(result, expected)
140+
msg = "use_inf_as_na option is deprecated"
141+
with tm.assert_produces_warning(FutureWarning, match=msg):
142+
with pd.option_context("mode.use_inf_as_na", True):
143+
cat = Categorical(values)
144+
result = cat.isna()
145+
tm.assert_numpy_array_equal(result, expected)
144146

145-
result = Series(cat).isna()
146-
expected = Series(expected)
147-
tm.assert_series_equal(result, expected)
147+
result = Series(cat).isna()
148+
expected = Series(expected)
149+
tm.assert_series_equal(result, expected)
148150

149-
result = DataFrame(cat).isna()
150-
expected = DataFrame(expected)
151-
tm.assert_frame_equal(result, expected)
151+
result = DataFrame(cat).isna()
152+
expected = DataFrame(expected)
153+
tm.assert_frame_equal(result, expected)
152154

153155
@pytest.mark.parametrize(
154156
"values, expected",
@@ -164,17 +166,19 @@ def test_use_inf_as_na_outside_context(self, values, expected):
164166
# Using isna directly for Categorical will fail in general here
165167
cat = Categorical(values)
166168

167-
with pd.option_context("mode.use_inf_as_na", True):
168-
result = isna(cat)
169-
tm.assert_numpy_array_equal(result, expected)
169+
msg = "use_inf_as_na option is deprecated"
170+
with tm.assert_produces_warning(FutureWarning, match=msg):
171+
with pd.option_context("mode.use_inf_as_na", True):
172+
result = isna(cat)
173+
tm.assert_numpy_array_equal(result, expected)
170174

171-
result = isna(Series(cat))
172-
expected = Series(expected)
173-
tm.assert_series_equal(result, expected)
175+
result = isna(Series(cat))
176+
expected = Series(expected)
177+
tm.assert_series_equal(result, expected)
174178

175-
result = isna(DataFrame(cat))
176-
expected = DataFrame(expected)
177-
tm.assert_frame_equal(result, expected)
179+
result = isna(DataFrame(cat))
180+
expected = DataFrame(expected)
181+
tm.assert_frame_equal(result, expected)
178182

179183
@pytest.mark.parametrize(
180184
"a1, a2, categories",

pandas/tests/arrays/string_/test_string.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -492,17 +492,19 @@ def test_value_counts_with_normalize(dtype):
492492
def test_use_inf_as_na(values, expected, dtype):
493493
# https://github.com/pandas-dev/pandas/issues/33655
494494
values = pd.array(values, dtype=dtype)
495-
with pd.option_context("mode.use_inf_as_na", True):
496-
result = values.isna()
497-
tm.assert_numpy_array_equal(result, expected)
498-
499-
result = pd.Series(values).isna()
500-
expected = pd.Series(expected)
501-
tm.assert_series_equal(result, expected)
502-
503-
result = pd.DataFrame(values).isna()
504-
expected = pd.DataFrame(expected)
505-
tm.assert_frame_equal(result, expected)
495+
msg = "use_inf_as_na option is deprecated"
496+
with tm.assert_produces_warning(FutureWarning, match=msg):
497+
with pd.option_context("mode.use_inf_as_na", True):
498+
result = values.isna()
499+
tm.assert_numpy_array_equal(result, expected)
500+
501+
result = pd.Series(values).isna()
502+
expected = pd.Series(expected)
503+
tm.assert_series_equal(result, expected)
504+
505+
result = pd.DataFrame(values).isna()
506+
expected = pd.DataFrame(expected)
507+
tm.assert_frame_equal(result, expected)
506508

507509

508510
def test_memory_usage(dtype):

pandas/tests/dtypes/test_missing.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,24 @@ def test_notna_notnull(notna_f):
5353
assert not notna_f(None)
5454
assert not notna_f(np.NaN)
5555

56-
with cf.option_context("mode.use_inf_as_na", False):
57-
assert notna_f(np.inf)
58-
assert notna_f(-np.inf)
56+
msg = "use_inf_as_na option is deprecated"
57+
with tm.assert_produces_warning(FutureWarning, match=msg):
58+
with cf.option_context("mode.use_inf_as_na", False):
59+
assert notna_f(np.inf)
60+
assert notna_f(-np.inf)
5961

60-
arr = np.array([1.5, np.inf, 3.5, -np.inf])
61-
result = notna_f(arr)
62-
assert result.all()
62+
arr = np.array([1.5, np.inf, 3.5, -np.inf])
63+
result = notna_f(arr)
64+
assert result.all()
6365

64-
with cf.option_context("mode.use_inf_as_na", True):
65-
assert not notna_f(np.inf)
66-
assert not notna_f(-np.inf)
66+
with tm.assert_produces_warning(FutureWarning, match=msg):
67+
with cf.option_context("mode.use_inf_as_na", True):
68+
assert not notna_f(np.inf)
69+
assert not notna_f(-np.inf)
6770

68-
arr = np.array([1.5, np.inf, 3.5, -np.inf])
69-
result = notna_f(arr)
70-
assert result.sum() == 2
71+
arr = np.array([1.5, np.inf, 3.5, -np.inf])
72+
result = notna_f(arr)
73+
assert result.sum() == 2
7174

7275

7376
@pytest.mark.parametrize("null_func", [notna, notnull, isna, isnull])
@@ -82,8 +85,10 @@ def test_notna_notnull(notna_f):
8285
],
8386
)
8487
def test_null_check_is_series(null_func, ser):
85-
with cf.option_context("mode.use_inf_as_na", False):
86-
assert isinstance(null_func(ser), Series)
88+
msg = "use_inf_as_na option is deprecated"
89+
with tm.assert_produces_warning(FutureWarning, match=msg):
90+
with cf.option_context("mode.use_inf_as_na", False):
91+
assert isinstance(null_func(ser), Series)
8792

8893

8994
class TestIsNA:
@@ -214,8 +219,10 @@ def test_isna_old_datetimelike(self):
214219
objs = [dta, dta.tz_localize("US/Eastern"), dta - dta, dta.to_period("D")]
215220

216221
for obj in objs:
217-
with cf.option_context("mode.use_inf_as_na", True):
218-
result = isna(obj)
222+
msg = "use_inf_as_na option is deprecated"
223+
with tm.assert_produces_warning(FutureWarning, match=msg):
224+
with cf.option_context("mode.use_inf_as_na", True):
225+
result = isna(obj)
219226

220227
tm.assert_numpy_array_equal(result, expected)
221228

pandas/tests/extension/base/missing.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ def test_fillna_fill_other(self, data):
154154
def test_use_inf_as_na_no_effect(self, data_missing):
155155
ser = pd.Series(data_missing)
156156
expected = ser.isna()
157-
with pd.option_context("mode.use_inf_as_na", True):
158-
result = ser.isna()
157+
msg = "use_inf_as_na option is deprecated"
158+
with tm.assert_produces_warning(FutureWarning, match=msg):
159+
with pd.option_context("mode.use_inf_as_na", True):
160+
result = ser.isna()
159161
self.assert_series_equal(result, expected)

0 commit comments

Comments
 (0)