Skip to content

Commit 33c1b21

Browse files
jbrockmendeljreback
authored andcommitted
REF: avoid getattr pattern for groupby-rank functions (#29166)
1 parent 9c21bb9 commit 33c1b21

File tree

3 files changed

+13
-24
lines changed

3 files changed

+13
-24
lines changed

pandas/_libs/groupby.pyx

-20
Original file line numberDiff line numberDiff line change
@@ -923,12 +923,6 @@ def group_last(rank_t[:, :] out,
923923
raise RuntimeError("empty group with uint64_t")
924924

925925

926-
group_last_float64 = group_last["float64_t"]
927-
group_last_float32 = group_last["float32_t"]
928-
group_last_int64 = group_last["int64_t"]
929-
group_last_object = group_last["object"]
930-
931-
932926
@cython.wraparound(False)
933927
@cython.boundscheck(False)
934928
def group_nth(rank_t[:, :] out,
@@ -1020,12 +1014,6 @@ def group_nth(rank_t[:, :] out,
10201014
raise RuntimeError("empty group with uint64_t")
10211015

10221016

1023-
group_nth_float64 = group_nth["float64_t"]
1024-
group_nth_float32 = group_nth["float32_t"]
1025-
group_nth_int64 = group_nth["int64_t"]
1026-
group_nth_object = group_nth["object"]
1027-
1028-
10291017
@cython.boundscheck(False)
10301018
@cython.wraparound(False)
10311019
def group_rank(float64_t[:, :] out,
@@ -1213,14 +1201,6 @@ def group_rank(float64_t[:, :] out,
12131201
out[i, 0] = out[i, 0] / grp_sizes[i, 0]
12141202

12151203

1216-
group_rank_float64 = group_rank["float64_t"]
1217-
group_rank_float32 = group_rank["float32_t"]
1218-
group_rank_int64 = group_rank["int64_t"]
1219-
group_rank_uint64 = group_rank["uint64_t"]
1220-
# Note: we do not have a group_rank_object because that would require a
1221-
# not-nogil implementation, see GH#19560
1222-
1223-
12241204
# ----------------------------------------------------------------------
12251205
# group_min, group_max
12261206
# ----------------------------------------------------------------------

pandas/core/groupby/ops.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -419,13 +419,21 @@ def get_func(fname):
419419

420420
# otherwise find dtype-specific version, falling back to object
421421
for dt in [dtype_str, "object"]:
422-
f = getattr(
422+
f2 = getattr(
423423
libgroupby,
424424
"{fname}_{dtype_str}".format(fname=fname, dtype_str=dt),
425425
None,
426426
)
427-
if f is not None:
428-
return f
427+
if f2 is not None:
428+
return f2
429+
430+
if hasattr(f, "__signatures__"):
431+
# inspect what fused types are implemented
432+
if dtype_str == "object" and "object" not in f.__signatures__:
433+
# return None so we get a NotImplementedError below
434+
# instead of a TypeError at runtime
435+
return None
436+
return f
429437

430438
ftype = self._cython_functions[kind][how]
431439

pandas/tests/groupby/test_rank.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import pandas as pd
55
from pandas import DataFrame, Series, concat
6+
from pandas.core.base import DataError
67
from pandas.util import testing as tm
78

89

@@ -384,7 +385,7 @@ def test_rank_avg_even_vals():
384385
def test_rank_object_raises(ties_method, ascending, na_option, pct, vals):
385386
df = DataFrame({"key": ["foo"] * 5, "val": vals})
386387

387-
with pytest.raises(TypeError, match="not callable"):
388+
with pytest.raises(DataError, match="No numeric types to aggregate"):
388389
df.groupby("key").rank(
389390
method=ties_method, ascending=ascending, na_option=na_option, pct=pct
390391
)

0 commit comments

Comments
 (0)