Skip to content

Commit 9c6176e

Browse files
rhshadrachpmhatre1
authored andcommitted
CLN: Enforce deprecation get_group with tuples of length 1 (pandas-dev#57743)
* CLN: Enforce deprecation get_group with tuples of length 1 * Add in similar deprecation involving iteration * type ignore
1 parent b397907 commit 9c6176e

File tree

4 files changed

+16
-42
lines changed

4 files changed

+16
-42
lines changed

doc/source/whatsnew/v3.0.0.rst

+2
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,12 @@ Removal of prior version deprecations/changes
200200
- All arguments in :meth:`Series.to_dict` are now keyword only (:issue:`56493`)
201201
- Changed the default value of ``observed`` in :meth:`DataFrame.groupby` and :meth:`Series.groupby` to ``True`` (:issue:`51811`)
202202
- Enforced deprecation disallowing parsing datetimes with mixed time zones unless user passes ``utc=True`` to :func:`to_datetime` (:issue:`57275`)
203+
- Enforced deprecation of :meth:`.DataFrameGroupBy.get_group` and :meth:`.SeriesGroupBy.get_group` allowing the ``name`` argument to be a non-tuple when grouping by a list of length 1 (:issue:`54155`)
203204
- Enforced deprecation of ``axis=None`` acting the same as ``axis=0`` in the DataFrame reductions ``sum``, ``prod``, ``std``, ``var``, and ``sem``, passing ``axis=None`` will now reduce over both axes; this is particularly the case when doing e.g. ``numpy.sum(df)`` (:issue:`21597`)
204205
- Enforced deprecation of passing a dictionary to :meth:`SeriesGroupBy.agg` (:issue:`52268`)
205206
- Enforced silent-downcasting deprecation for :ref:`all relevant methods <whatsnew_220.silent_downcasting>` (:issue:`54710`)
206207
- In :meth:`DataFrame.stack`, the default value of ``future_stack`` is now ``True``; specifying ``False`` will raise a ``FutureWarning`` (:issue:`55448`)
208+
- Iterating over a :class:`.DataFrameGroupBy` or :class:`.SeriesGroupBy` will return tuples of length 1 for the groups when grouping by ``level`` a list of length 1 (:issue:`50064`)
207209
- Methods ``apply``, ``agg``, and ``transform`` will no longer replace NumPy functions (e.g. ``np.sum``) and built-in functions (e.g. ``min``) with the equivalent pandas implementation; use string aliases (e.g. ``"sum"`` and ``"min"``) if you desire to use the pandas implementation (:issue:`53974`)
208210
- Passing both ``freq`` and ``fill_value`` in :meth:`DataFrame.shift` and :meth:`Series.shift` and :meth:`.DataFrameGroupBy.shift` now raises a ``ValueError`` (:issue:`54818`)
209211
- Removed :meth:`.DataFrameGroupBy.quantile` and :meth:`.SeriesGroupBy.quantile` supporting bool dtype (:issue:`53975`)

pandas/core/groupby/groupby.py

+7-22
Original file line numberDiff line numberDiff line change
@@ -919,17 +919,9 @@ def get_group(self, name) -> DataFrame | Series:
919919
):
920920
# GH#25971
921921
if isinstance(name, tuple) and len(name) == 1:
922-
# Allow users to pass tuples of length 1 to silence warning
923922
name = name[0]
924-
elif not isinstance(name, tuple):
925-
warnings.warn(
926-
"When grouping with a length-1 list-like, "
927-
"you will need to pass a length-1 tuple to get_group in a future "
928-
"version of pandas. Pass `(name,)` instead of `name` to silence "
929-
"this warning.",
930-
FutureWarning,
931-
stacklevel=find_stack_level(),
932-
)
923+
else:
924+
raise KeyError(name)
933925

934926
inds = self._get_index(name)
935927
if not len(inds):
@@ -1015,18 +1007,11 @@ def __iter__(self) -> Iterator[tuple[Hashable, NDFrameT]]:
10151007
keys = self.keys
10161008
level = self.level
10171009
result = self._grouper.get_iterator(self._selected_obj)
1018-
# error: Argument 1 to "len" has incompatible type "Hashable"; expected "Sized"
1019-
if is_list_like(level) and len(level) == 1: # type: ignore[arg-type]
1020-
# GH 51583
1021-
warnings.warn(
1022-
"Creating a Groupby object with a length-1 list-like "
1023-
"level parameter will yield indexes as tuples in a future version. "
1024-
"To keep indexes as scalars, create Groupby objects with "
1025-
"a scalar level parameter instead.",
1026-
FutureWarning,
1027-
stacklevel=find_stack_level(),
1028-
)
1029-
if isinstance(keys, list) and len(keys) == 1:
1010+
# mypy: Argument 1 to "len" has incompatible type "Hashable"; expected "Sized"
1011+
if (
1012+
(is_list_like(level) and len(level) == 1) # type: ignore[arg-type]
1013+
or (isinstance(keys, list) and len(keys) == 1)
1014+
):
10301015
# GH#42795 - when keys is a list, return tuples even when length is 1
10311016
result = (((key,), group) for key, group in result)
10321017
return result

pandas/tests/groupby/test_categorical.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -252,11 +252,7 @@ def test_level_get_group(observed):
252252
names=["Index1", "Index2"],
253253
),
254254
)
255-
msg = "you will need to pass a length-1 tuple"
256-
with tm.assert_produces_warning(FutureWarning, match=msg):
257-
# GH#25971 - warn when not passing a length-1 tuple
258-
result = g.get_group("a")
259-
255+
result = g.get_group(("a",))
260256
tm.assert_frame_equal(result, expected)
261257

262258

pandas/tests/groupby/test_groupby.py

+6-15
Original file line numberDiff line numberDiff line change
@@ -2529,19 +2529,14 @@ def test_groupby_string_dtype():
25292529
@pytest.mark.parametrize(
25302530
"level_arg, multiindex", [([0], False), ((0,), False), ([0], True), ((0,), True)]
25312531
)
2532-
def test_single_element_listlike_level_grouping_deprecation(level_arg, multiindex):
2532+
def test_single_element_listlike_level_grouping(level_arg, multiindex):
25332533
# GH 51583
25342534
df = DataFrame({"a": [1, 2], "b": [3, 4], "c": [5, 6]}, index=["x", "y"])
25352535
if multiindex:
25362536
df = df.set_index(["a", "b"])
2537-
depr_msg = (
2538-
"Creating a Groupby object with a length-1 list-like "
2539-
"level parameter will yield indexes as tuples in a future version. "
2540-
"To keep indexes as scalars, create Groupby objects with "
2541-
"a scalar level parameter instead."
2542-
)
2543-
with tm.assert_produces_warning(FutureWarning, match=depr_msg):
2544-
[key for key, _ in df.groupby(level=level_arg)]
2537+
result = [key for key, _ in df.groupby(level=level_arg)]
2538+
expected = [(1,), (2,)] if multiindex else [("x",), ("y",)]
2539+
assert result == expected
25452540

25462541

25472542
@pytest.mark.parametrize("func", ["sum", "cumsum", "cumprod", "prod"])
@@ -2880,22 +2875,18 @@ def test_groupby_series_with_datetimeindex_month_name():
28802875
"kwarg, value, name, warn",
28812876
[
28822877
("by", "a", 1, None),
2883-
("by", ["a"], 1, FutureWarning),
28842878
("by", ["a"], (1,), None),
28852879
("level", 0, 1, None),
2886-
("level", [0], 1, FutureWarning),
28872880
("level", [0], (1,), None),
28882881
],
28892882
)
2890-
def test_depr_get_group_len_1_list_likes(test_series, kwarg, value, name, warn):
2883+
def test_get_group_len_1_list_likes(test_series, kwarg, value, name, warn):
28912884
# GH#25971
28922885
obj = DataFrame({"b": [3, 4, 5]}, index=Index([1, 1, 2], name="a"))
28932886
if test_series:
28942887
obj = obj["b"]
28952888
gb = obj.groupby(**{kwarg: value})
2896-
msg = "you will need to pass a length-1 tuple"
2897-
with tm.assert_produces_warning(warn, match=msg):
2898-
result = gb.get_group(name)
2889+
result = gb.get_group(name)
28992890
if test_series:
29002891
expected = Series([3, 4], index=Index([1, 1], name="a"), name="b")
29012892
else:

0 commit comments

Comments
 (0)