diff --git a/pandas/_libs/reduction.pyx b/pandas/_libs/reduction.pyx index 11dc2d04bb74e..b95fe6c7bd13d 100644 --- a/pandas/_libs/reduction.pyx +++ b/pandas/_libs/reduction.pyx @@ -224,6 +224,7 @@ cdef class SeriesBinGrouper(_BaseGrouper): def __init__(self, object series, object f, object bins, object dummy): assert dummy is not None # always obj[:0] + assert len(bins) > 0 # otherwise we get IndexError in get_result self.bins = bins self.f = f diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index dda98d2dd438b..becca605e4485 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -262,10 +262,7 @@ def aggregate(self, func=None, *args, **kwargs): try: return self._python_agg_general(func, *args, **kwargs) - except (ValueError, KeyError, AttributeError, IndexError): - # TODO: IndexError can be removed here following GH#29106 - # TODO: AttributeError is caused by _index_data hijinx in - # libreduction, can be removed after GH#29160 + except (ValueError, KeyError): # TODO: KeyError is raised in _python_agg_general, # see see test_groupby.test_basic result = self._aggregate_named(func, *args, **kwargs) diff --git a/pandas/core/groupby/ops.py b/pandas/core/groupby/ops.py index 390fe60ea02b4..754d67d329538 100644 --- a/pandas/core/groupby/ops.py +++ b/pandas/core/groupby/ops.py @@ -721,6 +721,10 @@ def __init__( self.mutated = mutated self.indexer = indexer + # These lengths must match, otherwise we could call agg_series + # with empty self.bins, which would raise in libreduction. + assert len(self.binlabels) == len(self.bins) + @cache_readonly def groups(self): """ dict {group name -> group labels} """ @@ -828,10 +832,10 @@ def groupings(self) -> "List[grouper.Grouping]": def agg_series(self, obj: Series, func): # Caller is responsible for checking ngroups != 0 assert self.ngroups != 0 + assert len(self.bins) > 0 # otherwise we'd get IndexError in get_result if is_extension_array_dtype(obj.dtype): - # pre-empty SeriesBinGrouper from raising TypeError - # TODO: watch out, this can return None + # pre-empt SeriesBinGrouper from raising TypeError return self._aggregate_series_pure_python(obj, func) dummy = obj[:0] diff --git a/pandas/core/resample.py b/pandas/core/resample.py index d980d5ba0be6e..79c808cb3951c 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -187,6 +187,7 @@ def _get_binner(self): """ binner, bins, binlabels = self._get_binner_for_time() + assert len(bins) == len(binlabels) bin_grouper = BinGrouper(bins, binlabels, indexer=self.groupby.indexer) return binner, bin_grouper