diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index e25049cecdc09..843bd49ed39ab 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -271,6 +271,7 @@ or ``matplotlib.Axes.plot``. See :ref:`plotting.formatters` for more. - Removed the previously deprecated ``reduce`` and ``broadcast`` arguments from :meth:`DataFrame.apply` (:issue:`18577`) - Removed the previously deprecated ``assert_raises_regex`` function in ``pandas.util.testing`` (:issue:`29174`) - Removed :meth:`Index.is_lexsorted_for_tuple` (:issue:`29305`) +- Removed support for nexted renaming in :meth:`DataFrame.aggregate`, :meth:`Series.aggregate`, :meth:`DataFrameGroupBy.aggregate`, :meth:`SeriesGroupBy.aggregate`, :meth:`Rolling.aggregate` (:issue:`29608`) - .. _whatsnew_1000.performance: diff --git a/pandas/core/base.py b/pandas/core/base.py index e070005c56d7a..c9855701eeb03 100644 --- a/pandas/core/base.py +++ b/pandas/core/base.py @@ -283,9 +283,7 @@ def _try_aggregate_string_function(self, arg: str, *args, **kwargs): # people may try to aggregate on a non-callable attribute # but don't let them think they can pass args to it assert len(args) == 0 - assert ( - len([kwarg for kwarg in kwargs if kwarg not in ["axis", "_level"]]) == 0 - ) + assert len([kwarg for kwarg in kwargs if kwarg not in ["axis"]]) == 0 return f f = getattr(np, arg, None) @@ -324,34 +322,17 @@ def _aggregate(self, arg, *args, **kwargs): _axis = kwargs.pop("_axis", None) if _axis is None: _axis = getattr(self, "axis", 0) - _level = kwargs.pop("_level", None) if isinstance(arg, str): return self._try_aggregate_string_function(arg, *args, **kwargs), None if isinstance(arg, dict): - # aggregate based on the passed dict if _axis != 0: # pragma: no cover raise ValueError("Can only pass dict with axis=0") obj = self._selected_obj - def nested_renaming_depr(level: int = 4): - # deprecation of nested renaming - # GH 15931 - msg = textwrap.dedent( - """\ - using a dict with renaming is deprecated and will be removed - in a future version. - - For column-specific groupby renaming, use named aggregation - - >>> df.groupby(...).agg(name=('column', aggfunc)) - """ - ) - warnings.warn(msg, FutureWarning, stacklevel=level) - # if we have a dict of any non-scalars # eg. {'A' : ['mean']}, normalize all to # be list-likes @@ -374,18 +355,9 @@ def nested_renaming_depr(level: int = 4): # not ok # {'ra' : { 'A' : 'mean' }} if isinstance(v, dict): - is_nested_renamer = True - - if k not in obj.columns: - msg = ( - "cannot perform renaming for {key} with a " - "nested dictionary" - ).format(key=k) - raise SpecificationError(msg) - nested_renaming_depr(4 + (_level or 0)) - + raise SpecificationError("nested renamer is not supported") elif isinstance(obj, ABCSeries): - nested_renaming_depr() + raise SpecificationError("nested renamer is not supported") elif isinstance(obj, ABCDataFrame) and k not in obj.columns: raise KeyError("Column '{col}' does not exist!".format(col=k)) @@ -398,7 +370,7 @@ def nested_renaming_depr(level: int = 4): if isinstance(obj, ABCDataFrame) and len( obj.columns.intersection(keys) ) != len(keys): - nested_renaming_depr() + raise SpecificationError("nested renamer is not supported") from pandas.core.reshape.concat import concat @@ -411,14 +383,14 @@ def _agg_1dim(name, how, subset=None): raise SpecificationError( "nested dictionary is ambiguous in aggregation" ) - return colg.aggregate(how, _level=(_level or 0) + 1) + return colg.aggregate(how) def _agg_2dim(name, how): """ aggregate a 2-dim with how """ colg = self._gotitem(self._selection, ndim=2, subset=obj) - return colg.aggregate(how, _level=None) + return colg.aggregate(how) def _agg(arg, func): """ @@ -535,7 +507,7 @@ def is_any_frame() -> bool: return result, True elif is_list_like(arg): # we require a list, but not an 'str' - return self._aggregate_multiple_funcs(arg, _level=_level, _axis=_axis), None + return self._aggregate_multiple_funcs(arg, _axis=_axis), None else: result = None @@ -546,7 +518,7 @@ def is_any_frame() -> bool: # caller can react return result, True - def _aggregate_multiple_funcs(self, arg, _level, _axis): + def _aggregate_multiple_funcs(self, arg, _axis): from pandas.core.reshape.concat import concat if _axis != 0: diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index 31563e4bccbb7..0ca6ef043fffb 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -11,7 +11,6 @@ from textwrap import dedent import typing from typing import Any, Callable, FrozenSet, Iterable, Sequence, Type, Union, cast -import warnings import numpy as np @@ -213,7 +212,6 @@ def apply(self, func, *args, **kwargs): ) @Appender(_shared_docs["aggregate"]) def aggregate(self, func=None, *args, **kwargs): - _level = kwargs.pop("_level", None) relabeling = func is None columns = None @@ -232,7 +230,7 @@ def aggregate(self, func=None, *args, **kwargs): # Catch instances of lists / tuples # but not the class list / tuple itself. func = _maybe_mangle_lambdas(func) - ret = self._aggregate_multiple_funcs(func, (_level or 0) + 1) + ret = self._aggregate_multiple_funcs(func) if relabeling: ret.columns = columns else: @@ -256,8 +254,7 @@ def aggregate(self, func=None, *args, **kwargs): if not self.as_index: # pragma: no cover print("Warning, ignoring as_index=True") - # _level handled at higher - if not _level and isinstance(ret, dict): + if isinstance(ret, dict): from pandas import concat ret = concat(ret, axis=1) @@ -265,23 +262,14 @@ def aggregate(self, func=None, *args, **kwargs): agg = aggregate - def _aggregate_multiple_funcs(self, arg, _level): + def _aggregate_multiple_funcs(self, arg): if isinstance(arg, dict): # show the deprecation, but only if we # have not shown a higher level one # GH 15931 - if isinstance(self._selected_obj, Series) and _level <= 1: - msg = dedent( - """\ - using a dict on a Series for aggregation - is deprecated and will be removed in a future version. Use \ - named aggregation instead. - - >>> grouper.agg(name_1=func_1, name_2=func_2) - """ - ) - warnings.warn(msg, FutureWarning, stacklevel=3) + if isinstance(self._selected_obj, Series): + raise SpecificationError("nested renamer is not supported") columns = list(arg.keys()) arg = arg.items() @@ -317,8 +305,7 @@ def _aggregate_multiple_funcs(self, arg, _level): if any(isinstance(x, DataFrame) for x in results.values()): # let higher level handle - if _level: - return results + return results return DataFrame(results, columns=columns) @@ -845,7 +832,6 @@ class DataFrameGroupBy(GroupBy): ) @Appender(_shared_docs["aggregate"]) def aggregate(self, func=None, *args, **kwargs): - _level = kwargs.pop("_level", None) relabeling = func is None and _is_multi_agg_with_relabel(**kwargs) if relabeling: @@ -858,7 +844,7 @@ def aggregate(self, func=None, *args, **kwargs): func = _maybe_mangle_lambdas(func) - result, how = self._aggregate(func, _level=_level, *args, **kwargs) + result, how = self._aggregate(func, *args, **kwargs) if how is None: return result @@ -878,9 +864,7 @@ def aggregate(self, func=None, *args, **kwargs): # try to treat as if we are passing a list try: - result = self._aggregate_multiple_funcs( - [func], _level=_level, _axis=self.axis - ) + result = self._aggregate_multiple_funcs([func], _axis=self.axis) except ValueError as err: if "no results" not in str(err): # raised directly by _aggregate_multiple_funcs diff --git a/pandas/tests/frame/test_apply.py b/pandas/tests/frame/test_apply.py index ad53fcf29c57d..3c97a87c95bd2 100644 --- a/pandas/tests/frame/test_apply.py +++ b/pandas/tests/frame/test_apply.py @@ -13,6 +13,7 @@ from pandas import DataFrame, MultiIndex, Series, Timestamp, date_range, notna from pandas.conftest import _get_cython_table_params from pandas.core.apply import frame_apply +from pandas.core.base import SpecificationError import pandas.util.testing as tm @@ -1094,7 +1095,8 @@ def test_agg_dict_nested_renaming_depr(self): df = pd.DataFrame({"A": range(5), "B": 5}) # nested renaming - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + msg = r"nested renamer is not supported" + with pytest.raises(SpecificationError, match=msg): df.agg({"A": {"foo": "min"}, "B": {"bar": "max"}}) def test_agg_reduce(self, axis, float_frame): diff --git a/pandas/tests/groupby/aggregate/test_aggregate.py b/pandas/tests/groupby/aggregate/test_aggregate.py index 113c2c6d6d4ac..ea986058616d7 100644 --- a/pandas/tests/groupby/aggregate/test_aggregate.py +++ b/pandas/tests/groupby/aggregate/test_aggregate.py @@ -267,16 +267,16 @@ def bar(x): return np.std(x, ddof=1) # this uses column selection & renaming - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + msg = r"nested renamer is not supported" + with pytest.raises(SpecificationError, match=msg): d = OrderedDict( [["C", np.mean], ["D", OrderedDict([["foo", np.mean], ["bar", np.std]])]] ) - result = grouped.aggregate(d) + grouped.aggregate(d) + # But without renaming, these functions are OK d = OrderedDict([["C", [np.mean]], ["D", [foo, bar]]]) - expected = grouped.aggregate(d) - - tm.assert_frame_equal(result, expected) + grouped.aggregate(d) def test_multi_function_flexible_mix(df): @@ -288,26 +288,25 @@ def test_multi_function_flexible_mix(df): [["C", OrderedDict([["foo", "mean"], ["bar", "std"]])], ["D", {"sum": "sum"}]] ) # this uses column selection & renaming - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - expected = grouped.aggregate(d) + msg = r"nested renamer is not supported" + with pytest.raises(SpecificationError, match=msg): + grouped.aggregate(d) # Test 1 d = OrderedDict( [["C", OrderedDict([["foo", "mean"], ["bar", "std"]])], ["D", "sum"]] ) # this uses column selection & renaming - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = grouped.aggregate(d) - tm.assert_frame_equal(result, expected) + with pytest.raises(SpecificationError, match=msg): + grouped.aggregate(d) # Test 2 d = OrderedDict( [["C", OrderedDict([["foo", "mean"], ["bar", "std"]])], ["D", ["sum"]]] ) # this uses column selection & renaming - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = grouped.aggregate(d) - tm.assert_frame_equal(result, expected) + with pytest.raises(SpecificationError, match=msg): + grouped.aggregate(d) def test_groupby_agg_coercing_bools(): diff --git a/pandas/tests/groupby/aggregate/test_other.py b/pandas/tests/groupby/aggregate/test_other.py index 721045f1097f8..f14384928b979 100644 --- a/pandas/tests/groupby/aggregate/test_other.py +++ b/pandas/tests/groupby/aggregate/test_other.py @@ -211,31 +211,26 @@ def test_aggregate_api_consistency(): expected = pd.concat([c_mean, c_sum, d_mean, d_sum], axis=1) expected.columns = MultiIndex.from_product([["C", "D"], ["mean", "sum"]]) - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = grouped[["D", "C"]].agg({"r": np.sum, "r2": np.mean}) - expected = pd.concat([d_sum, c_sum, d_mean, c_mean], axis=1) - expected.columns = MultiIndex.from_product([["r", "r2"], ["D", "C"]]) - tm.assert_frame_equal(result, expected, check_like=True) + msg = r"nested renamer is not supported" + with pytest.raises(SpecificationError, match=msg): + grouped[["D", "C"]].agg({"r": np.sum, "r2": np.mean}) def test_agg_dict_renaming_deprecation(): # 15931 df = pd.DataFrame({"A": [1, 1, 1, 2, 2], "B": range(5), "C": range(5)}) - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False) as w: + msg = r"nested renamer is not supported" + with pytest.raises(SpecificationError, match=msg): df.groupby("A").agg( {"B": {"foo": ["sum", "max"]}, "C": {"bar": ["count", "min"]}} ) - assert "using a dict with renaming" in str(w[0].message) - assert "named aggregation" in str(w[0].message) - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + with pytest.raises(SpecificationError, match=msg): df.groupby("A")[["B", "C"]].agg({"ma": "max"}) - with tm.assert_produces_warning(FutureWarning) as w: + with pytest.raises(SpecificationError, match=msg): df.groupby("A").B.agg({"foo": "count"}) - assert "using a dict on a Series for aggregation" in str(w[0].message) - assert "named aggregation instead." in str(w[0].message) def test_agg_compat(): @@ -251,18 +246,12 @@ def test_agg_compat(): g = df.groupby(["A", "B"]) - expected = pd.concat([g["D"].sum(), g["D"].std()], axis=1) - expected.columns = MultiIndex.from_tuples([("C", "sum"), ("C", "std")]) - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = g["D"].agg({"C": ["sum", "std"]}) - tm.assert_frame_equal(result, expected, check_like=True) - - expected = pd.concat([g["D"].sum(), g["D"].std()], axis=1) - expected.columns = ["C", "D"] + msg = r"nested renamer is not supported" + with pytest.raises(SpecificationError, match=msg): + g["D"].agg({"C": ["sum", "std"]}) - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = g["D"].agg({"C": "sum", "D": "std"}) - tm.assert_frame_equal(result, expected, check_like=True) + with pytest.raises(SpecificationError, match=msg): + g["D"].agg({"C": "sum", "D": "std"}) def test_agg_nested_dicts(): @@ -278,29 +267,20 @@ def test_agg_nested_dicts(): g = df.groupby(["A", "B"]) - msg = r"cannot perform renaming for r[1-2] with a nested dictionary" + msg = r"nested renamer is not supported" with pytest.raises(SpecificationError, match=msg): g.aggregate({"r1": {"C": ["mean", "sum"]}, "r2": {"D": ["mean", "sum"]}}) - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = g.agg({"C": {"ra": ["mean", "std"]}, "D": {"rb": ["mean", "std"]}}) - expected = pd.concat( - [g["C"].mean(), g["C"].std(), g["D"].mean(), g["D"].std()], axis=1 - ) - expected.columns = pd.MultiIndex.from_tuples( - [("ra", "mean"), ("ra", "std"), ("rb", "mean"), ("rb", "std")] - ) - tm.assert_frame_equal(result, expected, check_like=True) + with pytest.raises(SpecificationError, match=msg): + g.agg({"C": {"ra": ["mean", "std"]}, "D": {"rb": ["mean", "std"]}}) # same name as the original column # GH9052 - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - expected = g["D"].agg({"result1": np.sum, "result2": np.mean}) - expected = expected.rename(columns={"result1": "D"}) + with pytest.raises(SpecificationError, match=msg): + g["D"].agg({"result1": np.sum, "result2": np.mean}) - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = g["D"].agg({"D": np.sum, "result2": np.mean}) - tm.assert_frame_equal(result, expected, check_like=True) + with pytest.raises(SpecificationError, match=msg): + g["D"].agg({"D": np.sum, "result2": np.mean}) def test_agg_item_by_item_raise_typeerror(): diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py index e17181f55fdba..0d68ff36dfa20 100644 --- a/pandas/tests/groupby/test_groupby.py +++ b/pandas/tests/groupby/test_groupby.py @@ -10,6 +10,7 @@ import pandas as pd from pandas import DataFrame, Index, MultiIndex, Series, Timestamp, date_range, read_csv +from pandas.core.base import SpecificationError import pandas.core.common as com import pandas.util.testing as tm @@ -55,8 +56,9 @@ def test_basic(dtype): # complex agg agged = grouped.aggregate([np.mean, np.std]) - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - agged = grouped.aggregate({"one": np.mean, "two": np.std}) + msg = r"nested renamer is not supported" + with pytest.raises(SpecificationError, match=msg): + grouped.aggregate({"one": np.mean, "two": np.std}) group_constants = {0: 10, 1: 20, 2: 30} agged = grouped.agg(lambda x: group_constants[x.name] + x.mean()) @@ -452,9 +454,9 @@ def test_frame_set_name_single(df): result = grouped["C"].agg([np.mean, np.std]) assert result.index.name == "A" - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = grouped["C"].agg({"foo": np.mean, "bar": np.std}) - assert result.index.name == "A" + msg = r"nested renamer is not supported" + with pytest.raises(SpecificationError, match=msg): + grouped["C"].agg({"foo": np.mean, "bar": np.std}) def test_multi_func(df): @@ -602,12 +604,10 @@ def test_groupby_as_index_agg(df): tm.assert_frame_equal(result2, expected2) grouped = df.groupby("A", as_index=True) - expected3 = grouped["C"].sum() - expected3 = DataFrame(expected3).rename(columns={"C": "Q"}) - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result3 = grouped["C"].agg({"Q": np.sum}) - tm.assert_frame_equal(result3, expected3) + msg = r"nested renamer is not supported" + with pytest.raises(SpecificationError, match=msg): + grouped["C"].agg({"Q": np.sum}) # multi-key diff --git a/pandas/tests/resample/test_resample_api.py b/pandas/tests/resample/test_resample_api.py index cbdfbb7a3100b..8e1774d8ee5b7 100644 --- a/pandas/tests/resample/test_resample_api.py +++ b/pandas/tests/resample/test_resample_api.py @@ -247,10 +247,9 @@ def test_agg_consistency(): r = df.resample("3T") - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - expected = r[["A", "B", "C"]].agg({"r1": "mean", "r2": "sum"}) - result = r.agg({"r1": "mean", "r2": "sum"}) - tm.assert_frame_equal(result, expected, check_like=True) + msg = "nested renamer is not supported" + with pytest.raises(pd.core.base.SpecificationError, match=msg): + r.agg({"r1": "mean", "r2": "sum"}) # TODO: once GH 14008 is fixed, move these tests into @@ -307,26 +306,23 @@ def test_agg(): result = t["A"].aggregate(["mean", "sum"]) tm.assert_frame_equal(result, expected) - expected = pd.concat([a_mean, a_sum], axis=1) - expected.columns = pd.MultiIndex.from_tuples([("A", "mean"), ("A", "sum")]) + msg = "nested renamer is not supported" for t in cases: - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = t.aggregate({"A": {"mean": "mean", "sum": "sum"}}) - tm.assert_frame_equal(result, expected, check_like=True) + with pytest.raises(pd.core.base.SpecificationError, match=msg): + t.aggregate({"A": {"mean": "mean", "sum": "sum"}}) expected = pd.concat([a_mean, a_sum, b_mean, b_sum], axis=1) expected.columns = pd.MultiIndex.from_tuples( [("A", "mean"), ("A", "sum"), ("B", "mean2"), ("B", "sum2")] ) for t in cases: - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = t.aggregate( + with pytest.raises(pd.core.base.SpecificationError, match=msg): + t.aggregate( { "A": {"mean": "mean", "sum": "sum"}, "B": {"mean2": "mean", "sum2": "sum"}, } ) - tm.assert_frame_equal(result, expected, check_like=True) expected = pd.concat([a_mean, a_std, b_mean, b_std], axis=1) expected.columns = pd.MultiIndex.from_tuples( @@ -383,12 +379,10 @@ def test_agg_misc(): [("result1", "A"), ("result1", "B"), ("result2", "A"), ("result2", "B")] ) + msg = "nested renamer is not supported" for t in cases: - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = t[["A", "B"]].agg( - OrderedDict([("result1", np.sum), ("result2", np.mean)]) - ) - tm.assert_frame_equal(result, expected, check_like=True) + with pytest.raises(pd.core.base.SpecificationError, match=msg): + t[["A", "B"]].agg(OrderedDict([("result1", np.sum), ("result2", np.mean)])) # agg with different hows expected = pd.concat( @@ -408,21 +402,11 @@ def test_agg_misc(): # series like aggs for t in cases: - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = t["A"].agg({"A": ["sum", "std"]}) - expected = pd.concat([t["A"].sum(), t["A"].std()], axis=1) - expected.columns = pd.MultiIndex.from_tuples([("A", "sum"), ("A", "std")]) - tm.assert_frame_equal(result, expected, check_like=True) + with pytest.raises(pd.core.base.SpecificationError, match=msg): + t["A"].agg({"A": ["sum", "std"]}) - expected = pd.concat( - [t["A"].agg(["sum", "std"]), t["A"].agg(["mean", "std"])], axis=1 - ) - expected.columns = pd.MultiIndex.from_tuples( - [("A", "sum"), ("A", "std"), ("B", "mean"), ("B", "std")] - ) - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = t["A"].agg({"A": ["sum", "std"], "B": ["mean", "std"]}) - tm.assert_frame_equal(result, expected, check_like=True) + with pytest.raises(pd.core.base.SpecificationError, match=msg): + t["A"].agg({"A": ["sum", "std"], "B": ["mean", "std"]}) # errors # invalid names in the agg specification @@ -451,28 +435,20 @@ def test_agg_nested_dicts(): df.groupby(pd.Grouper(freq="2D")), ] - msg = r"cannot perform renaming for r(1|2) with a nested dictionary" + msg = "nested renamer is not supported" for t in cases: with pytest.raises(pd.core.base.SpecificationError, match=msg): t.aggregate({"r1": {"A": ["mean", "sum"]}, "r2": {"B": ["mean", "sum"]}}) for t in cases: - expected = pd.concat( - [t["A"].mean(), t["A"].std(), t["B"].mean(), t["B"].std()], axis=1 - ) - expected.columns = pd.MultiIndex.from_tuples( - [("ra", "mean"), ("ra", "std"), ("rb", "mean"), ("rb", "std")] - ) - - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = t[["A", "B"]].agg( + + with pytest.raises(pd.core.base.SpecificationError, match=msg): + t[["A", "B"]].agg( {"A": {"ra": ["mean", "std"]}, "B": {"rb": ["mean", "std"]}} ) - tm.assert_frame_equal(result, expected, check_like=True) - with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - result = t.agg({"A": {"ra": ["mean", "std"]}, "B": {"rb": ["mean", "std"]}}) - tm.assert_frame_equal(result, expected, check_like=True) + with pytest.raises(pd.core.base.SpecificationError, match=msg): + t.agg({"A": {"ra": ["mean", "std"]}, "B": {"rb": ["mean", "std"]}}) def test_try_aggregate_non_existing_column(): diff --git a/pandas/tests/series/test_apply.py b/pandas/tests/series/test_apply.py index 09c5247ef616a..bdbfa333ef33a 100644 --- a/pandas/tests/series/test_apply.py +++ b/pandas/tests/series/test_apply.py @@ -7,6 +7,7 @@ import pandas as pd from pandas import DataFrame, Index, Series, isna from pandas.conftest import _get_cython_table_params +from pandas.core.base import SpecificationError import pandas.util.testing as tm @@ -157,7 +158,8 @@ def test_apply_dict_depr(self): columns=["A", "B", "C"], index=pd.date_range("1/1/2000", periods=10), ) - with tm.assert_produces_warning(FutureWarning): + msg = "nested renamer is not supported" + with pytest.raises(SpecificationError, match=msg): tsdf.A.agg({"foo": ["sum", "mean"]}) @pytest.mark.parametrize("series", [["1-1", "1-1", np.NaN], ["1-1", "1-2", np.NaN]]) @@ -256,31 +258,17 @@ def test_demo(self): tm.assert_series_equal(result, expected) # nested renaming - with tm.assert_produces_warning(FutureWarning): - result = s.agg({"foo": ["min", "max"]}) - - expected = ( - DataFrame({"foo": [0, 5]}, index=["min", "max"]).unstack().rename("series") - ) - tm.assert_series_equal(result, expected) + msg = "nested renamer is not supported" + with pytest.raises(SpecificationError, match=msg): + s.agg({"foo": ["min", "max"]}) def test_multiple_aggregators_with_dict_api(self): s = Series(range(6), dtype="int64", name="series") # nested renaming - with tm.assert_produces_warning(FutureWarning): - result = s.agg({"foo": ["min", "max"], "bar": ["sum", "mean"]}) - - expected = ( - DataFrame( - {"foo": [5.0, np.nan, 0.0, np.nan], "bar": [np.nan, 2.5, np.nan, 15.0]}, - columns=["foo", "bar"], - index=["max", "mean", "min", "sum"], - ) - .unstack() - .rename("series") - ) - tm.assert_series_equal(result.reindex_like(expected), expected) + msg = "nested renamer is not supported" + with pytest.raises(SpecificationError, match=msg): + s.agg({"foo": ["min", "max"], "bar": ["sum", "mean"]}) def test_agg_apply_evaluate_lambdas_the_same(self, string_series): # test that we are evaluating row-by-row first diff --git a/pandas/tests/window/test_api.py b/pandas/tests/window/test_api.py index 11527efa4c39f..5085576cc96f0 100644 --- a/pandas/tests/window/test_api.py +++ b/pandas/tests/window/test_api.py @@ -1,6 +1,4 @@ from collections import OrderedDict -import warnings -from warnings import catch_warnings import numpy as np import pytest @@ -82,7 +80,6 @@ def test_agg(self): a_sum = r["A"].sum() b_mean = r["B"].mean() b_std = r["B"].std() - b_sum = r["B"].sum() result = r.aggregate([np.mean, np.std]) expected = concat([a_mean, a_std, b_mean, b_std], axis=1) @@ -104,26 +101,18 @@ def test_agg(self): expected.columns = ["mean", "sum"] tm.assert_frame_equal(result, expected) - with catch_warnings(record=True): + msg = "nested renamer is not supported" + with pytest.raises(SpecificationError, match=msg): # using a dict with renaming - warnings.simplefilter("ignore", FutureWarning) - result = r.aggregate({"A": {"mean": "mean", "sum": "sum"}}) - expected = concat([a_mean, a_sum], axis=1) - expected.columns = pd.MultiIndex.from_tuples([("A", "mean"), ("A", "sum")]) - tm.assert_frame_equal(result, expected, check_like=True) + r.aggregate({"A": {"mean": "mean", "sum": "sum"}}) - with catch_warnings(record=True): - warnings.simplefilter("ignore", FutureWarning) - result = r.aggregate( + with pytest.raises(SpecificationError, match=msg): + r.aggregate( { "A": {"mean": "mean", "sum": "sum"}, "B": {"mean2": "mean", "sum2": "sum"}, } ) - expected = concat([a_mean, a_sum, b_mean, b_sum], axis=1) - exp_cols = [("A", "mean"), ("A", "sum"), ("B", "mean2"), ("B", "sum2")] - expected.columns = pd.MultiIndex.from_tuples(exp_cols) - tm.assert_frame_equal(result, expected, check_like=True) result = r.aggregate({"A": ["mean", "std"], "B": ["mean", "std"]}) expected = concat([a_mean, a_std, b_mean, b_std], axis=1) @@ -168,7 +157,7 @@ def test_agg_nested_dicts(self): df = DataFrame({"A": range(5), "B": range(0, 10, 2)}) r = df.rolling(window=3) - msg = r"cannot perform renaming for (r1|r2) with a nested dictionary" + msg = "nested renamer is not supported" with pytest.raises(SpecificationError, match=msg): r.aggregate({"r1": {"A": ["mean", "sum"]}, "r2": {"B": ["mean", "sum"]}}) @@ -178,25 +167,13 @@ def test_agg_nested_dicts(self): expected.columns = pd.MultiIndex.from_tuples( [("ra", "mean"), ("ra", "std"), ("rb", "mean"), ("rb", "std")] ) - with catch_warnings(record=True): - warnings.simplefilter("ignore", FutureWarning) - result = r[["A", "B"]].agg( + with pytest.raises(SpecificationError, match=msg): + r[["A", "B"]].agg( {"A": {"ra": ["mean", "std"]}, "B": {"rb": ["mean", "std"]}} ) - tm.assert_frame_equal(result, expected, check_like=True) - with catch_warnings(record=True): - warnings.simplefilter("ignore", FutureWarning) - result = r.agg({"A": {"ra": ["mean", "std"]}, "B": {"rb": ["mean", "std"]}}) - expected.columns = pd.MultiIndex.from_tuples( - [ - ("A", "ra", "mean"), - ("A", "ra", "std"), - ("B", "rb", "mean"), - ("B", "rb", "std"), - ] - ) - tm.assert_frame_equal(result, expected, check_like=True) + with pytest.raises(SpecificationError, match=msg): + r.agg({"A": {"ra": ["mean", "std"]}, "B": {"rb": ["mean", "std"]}}) def test_count_nonnumeric_types(self): # GH12541