Skip to content

Commit d5b958a

Browse files
authored
Raise if None is passed for skipna (#44579)
1 parent 7aa19f0 commit d5b958a

File tree

5 files changed

+46
-24
lines changed

5 files changed

+46
-24
lines changed

doc/source/whatsnew/v1.4.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ Other API changes
399399
^^^^^^^^^^^^^^^^^
400400
- :meth:`Index.get_indexer_for` no longer accepts keyword arguments (other than 'target'); in the past these would be silently ignored if the index was not unique (:issue:`42310`)
401401
- Change in the position of the ``min_rows`` argument in :meth:`DataFrame.to_string` due to change in the docstring (:issue:`44304`)
402+
- Reduction operations for :class:`DataFrame` or :class:`Series` now raising a ``ValueError`` when ``None`` is passed for ``skipna`` (:issue:`44178`)
402403
-
403404

404405
.. ---------------------------------------------------------------------------

pandas/core/generic.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -10303,6 +10303,7 @@ def _logical_func(
1030310303
self, name: str, func, axis=0, bool_only=None, skipna=True, level=None, **kwargs
1030410304
):
1030510305
nv.validate_logical_func((), kwargs, fname=name)
10306+
validate_bool_kwarg(skipna, "skipna", none_allowed=False)
1030610307
if level is not None:
1030710308
warnings.warn(
1030810309
"Using the level keyword in DataFrame and Series aggregations is "
@@ -10397,6 +10398,7 @@ def _stat_function_ddof(
1039710398
**kwargs,
1039810399
):
1039910400
nv.validate_stat_ddof_func((), kwargs, fname=name)
10401+
validate_bool_kwarg(skipna, "skipna", none_allowed=False)
1040010402
if axis is None:
1040110403
axis = self._stat_axis_number
1040210404
if level is not None:
@@ -10450,6 +10452,9 @@ def _stat_function(
1045010452
nv.validate_median((), kwargs)
1045110453
else:
1045210454
nv.validate_stat_func((), kwargs, fname=name)
10455+
10456+
validate_bool_kwarg(skipna, "skipna", none_allowed=False)
10457+
1045310458
if axis is None:
1045410459
axis = self._stat_axis_number
1045510460
if level is not None:
@@ -10517,6 +10522,9 @@ def _min_count_stat_function(
1051710522
nv.validate_prod((), kwargs)
1051810523
else:
1051910524
nv.validate_stat_func((), kwargs, fname=name)
10525+
10526+
validate_bool_kwarg(skipna, "skipna", none_allowed=False)
10527+
1052010528
if axis is None:
1052110529
axis = self._stat_axis_number
1052210530
if level is not None:
@@ -10669,7 +10677,7 @@ def all(self, axis=0, bool_only=None, skipna=True, level=None, **kwargs):
1066910677
see_also="",
1067010678
examples="",
1067110679
)
10672-
def mad(self, axis=None, skipna=None, level=None):
10680+
def mad(self, axis=None, skipna=True, level=None):
1067310681
return NDFrame.mad(self, axis, skipna, level)
1067410682

1067510683
setattr(cls, "mad", mad)

pandas/tests/apply/test_str.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
pytest.param([1], {}, id="axis_from_args"),
2727
pytest.param([], {"axis": 1}, id="axis_from_kwds"),
2828
pytest.param([], {"numeric_only": True}, id="optional_kwds"),
29-
pytest.param([1, None], {"numeric_only": True}, id="args_and_kwds"),
29+
pytest.param([1, True], {"numeric_only": True}, id="args_and_kwds"),
3030
],
3131
)
3232
@pytest.mark.parametrize("how", ["agg", "apply"])

pandas/tests/frame/conftest.py

+23
Original file line numberDiff line numberDiff line change
@@ -259,3 +259,26 @@ def frame_of_index_cols():
259259
}
260260
)
261261
return df
262+
263+
264+
@pytest.fixture(
265+
params=[
266+
"any",
267+
"all",
268+
"count",
269+
"sum",
270+
"prod",
271+
"max",
272+
"min",
273+
"mean",
274+
"median",
275+
"skew",
276+
"kurt",
277+
"sem",
278+
"var",
279+
"std",
280+
"mad",
281+
]
282+
)
283+
def reduction_functions(request):
284+
return request.param

pandas/tests/frame/test_reductions.py

+12-22
Original file line numberDiff line numberDiff line change
@@ -1478,33 +1478,23 @@ def test_frame_any_with_timedelta(self):
14781478
expected = Series(data=[False, True])
14791479
tm.assert_series_equal(result, expected)
14801480

1481-
@pytest.mark.parametrize(
1482-
"func",
1483-
[
1484-
"any",
1485-
"all",
1486-
"count",
1487-
"sum",
1488-
"prod",
1489-
"max",
1490-
"min",
1491-
"mean",
1492-
"median",
1493-
"skew",
1494-
"kurt",
1495-
"sem",
1496-
"var",
1497-
"std",
1498-
"mad",
1499-
],
1500-
)
1501-
def test_reductions_deprecation_level_argument(self, frame_or_series, func):
1481+
def test_reductions_deprecation_level_argument(
1482+
self, frame_or_series, reduction_functions
1483+
):
15021484
# GH#39983
15031485
obj = frame_or_series(
15041486
[1, 2, 3], index=MultiIndex.from_arrays([[1, 2, 3], [4, 5, 6]])
15051487
)
15061488
with tm.assert_produces_warning(FutureWarning, match="level"):
1507-
getattr(obj, func)(level=0)
1489+
getattr(obj, reduction_functions)(level=0)
1490+
1491+
def test_reductions_skipna_none_raises(self, frame_or_series, reduction_functions):
1492+
if reduction_functions in ["count", "mad"]:
1493+
pytest.skip("Count does not accept skipna. Mad needs a depreaction cycle.")
1494+
obj = frame_or_series([1, 2, 3])
1495+
msg = 'For argument "skipna" expected type bool, received type NoneType.'
1496+
with pytest.raises(ValueError, match=msg):
1497+
getattr(obj, reduction_functions)(skipna=None)
15081498

15091499

15101500
class TestNuisanceColumns:

0 commit comments

Comments
 (0)