From 4a60a683dbdff5346f312dc52a8dca92c4b8f1b9 Mon Sep 17 00:00:00 2001 From: Will Ayd Date: Sun, 13 Oct 2019 14:42:52 -0700 Subject: [PATCH 1/5] Consistent return type of _iterate_slices --- pandas/core/groupby/generic.py | 40 ++++++++++++++++++++-------------- pandas/core/groupby/groupby.py | 4 ++-- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index 068d5e5275f0d..98675edc1d336 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -11,7 +11,17 @@ from functools import partial from textwrap import dedent import typing -from typing import Any, Callable, FrozenSet, Sequence, Type, Union +from typing import ( + Any, + Callable, + FrozenSet, + Hashable, + Iterator, + Sequence, + Tuple, + Type, + Union, +) import warnings import numpy as np @@ -132,7 +142,7 @@ def pinner(cls): class SeriesGroupBy(GroupBy): _apply_whitelist = base.series_apply_whitelist - def _iterate_slices(self): + def _iterate_slices(self) -> Iterator[Tuple[Hashable, Series]]: yield self._selection_name, self._selected_obj @property @@ -898,22 +908,20 @@ def aggregate(self, func=None, *args, **kwargs): agg = aggregate - def _iterate_slices(self): - if self.axis == 0: - # kludge - if self._selection is None: - slice_axis = self.obj.columns - else: - slice_axis = self._selection_list - slicer = lambda x: self.obj[x] + def _iterate_slices(self) -> Iterator[Tuple[Hashable, Series]]: + obj = self._selected_obj.copy() + if self.axis == 1: + obj = obj.T + + if isinstance(obj, Series) and obj.name not in self.exclusions: + # Occurs when doing DataFrameGroupBy(...)["X"] + yield obj.name, obj else: - slice_axis = self.obj.index - slicer = self.obj.xs + for label, values in obj.items(): + if label in self.exclusions: + continue - for val in slice_axis: - if val in self.exclusions: - continue - yield val, slicer(val) + yield label, values def _cython_agg_general(self, how, alt=None, numeric_only=True, min_count=-1): new_items, new_blocks = self._cython_agg_blocks( diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index cc297629a7004..0ba0087ef7c6d 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -14,7 +14,7 @@ class providing the base-class of operations. import inspect import re import types -from typing import FrozenSet, List, Optional, Tuple, Type, Union +from typing import FrozenSet, Hashable, Iterator, List, Optional, Tuple, Type, Union import numpy as np @@ -758,7 +758,7 @@ def _python_apply_general(self, f): keys, values, not_indexed_same=mutated or self.mutated ) - def _iterate_slices(self): + def _iterate_slices(self) -> Iterator[Tuple[Hashable, Series]]: raise AbstractMethodError(self) def transform(self, func, *args, **kwargs): From 5e29af0f90c2f510ed9cda353d6d7e72df14487e Mon Sep 17 00:00:00 2001 From: Will Ayd Date: Sun, 13 Oct 2019 15:08:00 -0700 Subject: [PATCH 2/5] Removed copy --- pandas/core/groupby/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index 98675edc1d336..76cb6ba48c665 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -909,7 +909,7 @@ def aggregate(self, func=None, *args, **kwargs): agg = aggregate def _iterate_slices(self) -> Iterator[Tuple[Hashable, Series]]: - obj = self._selected_obj.copy() + obj = self._selected_obj if self.axis == 1: obj = obj.T From 3f687943a1e20f4af1fbcb3045beb726960e0b11 Mon Sep 17 00:00:00 2001 From: Will Ayd Date: Sun, 13 Oct 2019 15:11:30 -0700 Subject: [PATCH 3/5] Annoted DataFrame.items as well --- pandas/core/frame.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 79e941f262931..097d7a99192f9 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -14,7 +14,18 @@ import itertools import sys from textwrap import dedent -from typing import FrozenSet, List, Optional, Sequence, Set, Tuple, Type, Union +from typing import ( + FrozenSet, + Hashable, + Iterator, + List, + Optional, + Sequence, + Set, + Tuple, + Type, + Union, +) import warnings import numpy as np @@ -861,7 +872,7 @@ def style(self): """ @Appender(_shared_docs["items"]) - def items(self): + def items(self) -> Iterator[Tuple[Hashable, Series]]: if self.columns.is_unique and hasattr(self, "_item_cache"): for k in self.columns: yield k, self._get_item_cache(k) From 4d94f637bdd9fdc888b068f8c1e9d98e4d8a2011 Mon Sep 17 00:00:00 2001 From: Will Ayd Date: Sun, 13 Oct 2019 15:13:53 -0700 Subject: [PATCH 4/5] Iterator -> Iterable --- pandas/core/frame.py | 4 ++-- pandas/core/groupby/generic.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 097d7a99192f9..c82d8a25fedba 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -17,7 +17,7 @@ from typing import ( FrozenSet, Hashable, - Iterator, + Iterable, List, Optional, Sequence, @@ -872,7 +872,7 @@ def style(self): """ @Appender(_shared_docs["items"]) - def items(self) -> Iterator[Tuple[Hashable, Series]]: + def items(self) -> Iterable[Tuple[Hashable, Series]]: if self.columns.is_unique and hasattr(self, "_item_cache"): for k in self.columns: yield k, self._get_item_cache(k) diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index 76cb6ba48c665..4125d6a918b26 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -16,7 +16,7 @@ Callable, FrozenSet, Hashable, - Iterator, + Iterable, Sequence, Tuple, Type, @@ -142,7 +142,7 @@ def pinner(cls): class SeriesGroupBy(GroupBy): _apply_whitelist = base.series_apply_whitelist - def _iterate_slices(self) -> Iterator[Tuple[Hashable, Series]]: + def _iterate_slices(self) -> Iterable[Tuple[Hashable, Series]]: yield self._selection_name, self._selected_obj @property @@ -908,7 +908,7 @@ def aggregate(self, func=None, *args, **kwargs): agg = aggregate - def _iterate_slices(self) -> Iterator[Tuple[Hashable, Series]]: + def _iterate_slices(self) -> Iterable[Tuple[Hashable, Series]]: obj = self._selected_obj if self.axis == 1: obj = obj.T From 4862742087eb5742a844bfc1383a03f6bf2fc311 Mon Sep 17 00:00:00 2001 From: Will Ayd Date: Sun, 13 Oct 2019 15:43:21 -0700 Subject: [PATCH 5/5] mypy fixes --- pandas/core/groupby/groupby.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 0ba0087ef7c6d..4ea02d59597f1 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -14,7 +14,7 @@ class providing the base-class of operations. import inspect import re import types -from typing import FrozenSet, Hashable, Iterator, List, Optional, Tuple, Type, Union +from typing import FrozenSet, Hashable, Iterable, List, Optional, Tuple, Type, Union import numpy as np @@ -758,7 +758,7 @@ def _python_apply_general(self, f): keys, values, not_indexed_same=mutated or self.mutated ) - def _iterate_slices(self) -> Iterator[Tuple[Hashable, Series]]: + def _iterate_slices(self) -> Iterable[Tuple[Hashable, Series]]: raise AbstractMethodError(self) def transform(self, func, *args, **kwargs):