Skip to content

Commit a82b8e2

Browse files
authored
REF: Define methods on resample non-dynamically (#50913)
* REF: Define methods on resample non-dynamically * Remove unused ignore
1 parent 74b13fa commit a82b8e2

File tree

2 files changed

+97
-89
lines changed

2 files changed

+97
-89
lines changed

pandas/core/groupby/groupby.py

-8
Original file line numberDiff line numberDiff line change
@@ -2004,8 +2004,6 @@ def mean(
20042004
return result.__finalize__(self.obj, method="groupby")
20052005

20062006
@final
2007-
@Substitution(name="groupby")
2008-
@Appender(_common_see_also)
20092007
def median(self, numeric_only: bool = False):
20102008
"""
20112009
Compute median of groups, excluding missing values.
@@ -2315,8 +2313,6 @@ def _value_counts(
23152313
return result.__finalize__(self.obj, method="value_counts")
23162314

23172315
@final
2318-
@Substitution(name="groupby")
2319-
@Appender(_common_see_also)
23202316
def sem(self, ddof: int = 1, numeric_only: bool = False):
23212317
"""
23222318
Compute standard error of the mean of groups, excluding missing values.
@@ -2471,7 +2467,6 @@ def max(
24712467
)
24722468

24732469
@final
2474-
@Substitution(name="groupby")
24752470
def first(self, numeric_only: bool = False, min_count: int = -1):
24762471
"""
24772472
Compute the first non-null entry of each column.
@@ -2542,7 +2537,6 @@ def first(x: Series):
25422537
)
25432538

25442539
@final
2545-
@Substitution(name="groupby")
25462540
def last(self, numeric_only: bool = False, min_count: int = -1):
25472541
"""
25482542
Compute the last non-null entry of each column.
@@ -2602,8 +2596,6 @@ def last(x: Series):
26022596
)
26032597

26042598
@final
2605-
@Substitution(name="groupby")
2606-
@Appender(_common_see_also)
26072599
def ohlc(self) -> DataFrame:
26082600
"""
26092601
Compute open, high, low and close values of a group, excluding missing values.

pandas/core/resample.py

+97-81
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,74 @@ def asfreq(self, fill_value=None):
895895
"""
896896
return self._upsample("asfreq", fill_value=fill_value)
897897

898+
def sum(
899+
self,
900+
numeric_only: bool = False,
901+
min_count: int = 0,
902+
*args,
903+
**kwargs,
904+
):
905+
nv.validate_resampler_func("sum", args, kwargs)
906+
return self._downsample("sum", numeric_only=numeric_only, min_count=min_count)
907+
908+
@doc(GroupBy.prod)
909+
def prod(
910+
self,
911+
numeric_only: bool = False,
912+
min_count: int = 0,
913+
*args,
914+
**kwargs,
915+
):
916+
nv.validate_resampler_func("prod", args, kwargs)
917+
return self._downsample("prod", numeric_only=numeric_only, min_count=min_count)
918+
919+
def min(
920+
self,
921+
numeric_only: bool = False,
922+
min_count: int = 0,
923+
*args,
924+
**kwargs,
925+
):
926+
nv.validate_resampler_func("min", args, kwargs)
927+
return self._downsample("min", numeric_only=numeric_only, min_count=min_count)
928+
929+
def max(
930+
self,
931+
numeric_only: bool = False,
932+
min_count: int = 0,
933+
*args,
934+
**kwargs,
935+
):
936+
nv.validate_resampler_func("max", args, kwargs)
937+
return self._downsample("max", numeric_only=numeric_only, min_count=min_count)
938+
939+
@doc(GroupBy.first)
940+
def first(
941+
self,
942+
numeric_only: bool = False,
943+
min_count: int = 0,
944+
*args,
945+
**kwargs,
946+
):
947+
nv.validate_resampler_func("first", args, kwargs)
948+
return self._downsample("first", numeric_only=numeric_only, min_count=min_count)
949+
950+
@doc(GroupBy.last)
951+
def last(
952+
self,
953+
numeric_only: bool = False,
954+
min_count: int = 0,
955+
*args,
956+
**kwargs,
957+
):
958+
nv.validate_resampler_func("last", args, kwargs)
959+
return self._downsample("last", numeric_only=numeric_only, min_count=min_count)
960+
961+
@doc(GroupBy.median)
962+
def median(self, numeric_only: bool = False, *args, **kwargs):
963+
nv.validate_resampler_func("median", args, kwargs)
964+
return self._downsample("median", numeric_only=numeric_only)
965+
898966
def mean(
899967
self,
900968
numeric_only: bool = False,
@@ -984,6 +1052,35 @@ def var(
9841052
nv.validate_resampler_func("var", args, kwargs)
9851053
return self._downsample("var", ddof=ddof, numeric_only=numeric_only)
9861054

1055+
@doc(GroupBy.sem)
1056+
def sem(
1057+
self,
1058+
ddof: int = 1,
1059+
numeric_only: bool = False,
1060+
*args,
1061+
**kwargs,
1062+
):
1063+
nv.validate_resampler_func("sem", args, kwargs)
1064+
return self._downsample("sem", ddof=ddof, numeric_only=numeric_only)
1065+
1066+
@doc(GroupBy.ohlc)
1067+
def ohlc(
1068+
self,
1069+
*args,
1070+
**kwargs,
1071+
):
1072+
nv.validate_resampler_func("ohlc", args, kwargs)
1073+
return self._downsample("ohlc")
1074+
1075+
@doc(SeriesGroupBy.nunique)
1076+
def nunique(
1077+
self,
1078+
*args,
1079+
**kwargs,
1080+
):
1081+
nv.validate_resampler_func("nunique", args, kwargs)
1082+
return self._downsample("nunique")
1083+
9871084
@doc(GroupBy.size)
9881085
def size(self):
9891086
result = self._downsample("size")
@@ -1047,87 +1144,6 @@ def quantile(self, q: float | AnyArrayLike = 0.5, **kwargs):
10471144
return self._downsample("quantile", q=q, **kwargs)
10481145

10491146

1050-
def _add_downsample_kernel(
1051-
name: str, args: tuple[str, ...], docs_class: type = GroupBy
1052-
) -> None:
1053-
"""
1054-
Add a kernel to Resampler.
1055-
1056-
Arguments
1057-
---------
1058-
name : str
1059-
Name of the kernel.
1060-
args : tuple
1061-
Arguments of the method.
1062-
docs_class : type
1063-
Class to get kernel docstring from.
1064-
"""
1065-
assert args in (
1066-
("numeric_only", "min_count"),
1067-
("numeric_only",),
1068-
("ddof", "numeric_only"),
1069-
(),
1070-
)
1071-
1072-
# Explicitly provide args rather than args/kwargs for API docs
1073-
if args == ("numeric_only", "min_count"):
1074-
1075-
def f(
1076-
self,
1077-
numeric_only: bool = False,
1078-
min_count: int = 0,
1079-
*args,
1080-
**kwargs,
1081-
):
1082-
nv.validate_resampler_func(name, args, kwargs)
1083-
return self._downsample(
1084-
name, numeric_only=numeric_only, min_count=min_count
1085-
)
1086-
1087-
elif args == ("numeric_only",):
1088-
# error: All conditional function variants must have identical signatures
1089-
def f(self, numeric_only: bool = False, *args, **kwargs): # type: ignore[misc]
1090-
nv.validate_resampler_func(name, args, kwargs)
1091-
return self._downsample(name, numeric_only=numeric_only)
1092-
1093-
elif args == ("ddof", "numeric_only"):
1094-
# error: All conditional function variants must have identical signatures
1095-
def f( # type: ignore[misc]
1096-
self,
1097-
ddof: int = 1,
1098-
numeric_only: bool = False,
1099-
*args,
1100-
**kwargs,
1101-
):
1102-
nv.validate_resampler_func(name, args, kwargs)
1103-
return self._downsample(name, ddof=ddof, numeric_only=numeric_only)
1104-
1105-
else:
1106-
# error: All conditional function variants must have identical signatures
1107-
def f( # type: ignore[misc]
1108-
self,
1109-
*args,
1110-
**kwargs,
1111-
):
1112-
nv.validate_resampler_func(name, args, kwargs)
1113-
return self._downsample(name)
1114-
1115-
f.__doc__ = getattr(docs_class, name).__doc__
1116-
setattr(Resampler, name, f)
1117-
1118-
1119-
for _method in ["sum", "prod", "min", "max", "first", "last"]:
1120-
_add_downsample_kernel(_method, ("numeric_only", "min_count"))
1121-
for _method in ["median"]:
1122-
_add_downsample_kernel(_method, ("numeric_only",))
1123-
for _method in ["sem"]:
1124-
_add_downsample_kernel(_method, ("ddof", "numeric_only"))
1125-
for _method in ["ohlc"]:
1126-
_add_downsample_kernel(_method, ())
1127-
for _method in ["nunique"]:
1128-
_add_downsample_kernel(_method, (), SeriesGroupBy)
1129-
1130-
11311147
class _GroupByMixin(PandasObject):
11321148
"""
11331149
Provide the groupby facilities.

0 commit comments

Comments
 (0)