Skip to content

Commit d57109f

Browse files
jbrockmendelMateusz Górski
authored and
Mateusz Górski
committed
REF: Pre-empt ValueError in _aggregate_series_fast (pandas-dev#29500)
1 parent 37377e4 commit d57109f

File tree

3 files changed

+24
-7
lines changed

3 files changed

+24
-7
lines changed

pandas/_libs/reduction.pyx

+7-2
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,10 @@ cdef class SeriesGrouper(_BaseGrouper):
323323
# safer obj._get_values(slice(None, 0))
324324
assert dummy is not None
325325

326+
if len(series) == 0:
327+
# get_result would never assign `result`
328+
raise ValueError("SeriesGrouper requires non-empty `series`")
329+
326330
self.labels = labels
327331
self.f = f
328332

@@ -408,8 +412,9 @@ cdef class SeriesGrouper(_BaseGrouper):
408412
islider.reset()
409413
vslider.reset()
410414

411-
if result is None:
412-
raise ValueError("No result.")
415+
# We check for empty series in the constructor, so should always
416+
# have result initialized by this point.
417+
assert result is not None, "`result` has not been assigned."
413418

414419
if result.dtype == np.object_:
415420
result = maybe_convert_objects(result)

pandas/core/groupby/ops.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,11 @@ def agg_series(self, obj: Series, func):
604604
# Caller is responsible for checking ngroups != 0
605605
assert self.ngroups != 0
606606

607-
if is_extension_array_dtype(obj.dtype) and obj.dtype.kind != "M":
607+
if len(obj) == 0:
608+
# SeriesGrouper would raise if we were to call _aggregate_series_fast
609+
return self._aggregate_series_pure_python(obj, func)
610+
611+
elif is_extension_array_dtype(obj.dtype) and obj.dtype.kind != "M":
608612
# _aggregate_series_fast would raise TypeError when
609613
# calling libreduction.Slider
610614
# TODO: can we get a performant workaround for EAs backed by ndarray?
@@ -618,10 +622,7 @@ def agg_series(self, obj: Series, func):
618622
try:
619623
return self._aggregate_series_fast(obj, func)
620624
except ValueError as err:
621-
if "No result." in str(err):
622-
# raised in libreduction
623-
pass
624-
elif "Function does not reduce" in str(err):
625+
if "Function does not reduce" in str(err):
625626
# raised in libreduction
626627
pass
627628
else:
@@ -632,6 +633,7 @@ def _aggregate_series_fast(self, obj, func):
632633
# At this point we have already checked that
633634
# - obj.index is not a MultiIndex
634635
# - obj is backed by an ndarray, not ExtensionArray
636+
# - len(obj) > 0
635637
# - ngroups != 0
636638
func = self._is_builtin_func(func)
637639

pandas/tests/groupby/test_bin_groupby.py

+10
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ def test_series_grouper():
2525
tm.assert_almost_equal(counts, exp_counts)
2626

2727

28+
def test_series_grouper_requires_nonempty_raises():
29+
# GH#29500
30+
obj = Series(np.random.randn(10))
31+
dummy = obj[:0]
32+
labels = np.array([-1, -1, -1, 0, 0, 0, 1, 1, 1, 1], dtype=np.int64)
33+
34+
with pytest.raises(ValueError, match="SeriesGrouper requires non-empty `series`"):
35+
libreduction.SeriesGrouper(dummy, np.mean, labels, 2, dummy)
36+
37+
2838
def test_series_bin_grouper():
2939
obj = Series(np.random.randn(10))
3040
dummy = obj[:0]

0 commit comments

Comments
 (0)