Skip to content

Commit 4e8ccf6

Browse files
committed
code impl and examples
1 parent b20d6ab commit 4e8ccf6

File tree

1 file changed

+47
-4
lines changed

1 file changed

+47
-4
lines changed

pandas/core/groupby/generic.py

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
TYPE_CHECKING,
1717
Any,
1818
Literal,
19-
NamedTuple,
2019
TypeAlias,
2120
TypeVar,
2221
cast,
@@ -113,11 +112,32 @@
113112

114113

115114
@set_module("pandas")
116-
class NamedAgg(NamedTuple):
115+
class NamedAgg(tuple):
116+
__slots__ = ()
117+
118+
def __new__(cls, column, aggfunc, *args, **kwargs):
119+
if (
120+
callable(aggfunc)
121+
and not getattr(aggfunc, "_is_wrapped", False)
122+
and (args or kwargs)
123+
):
124+
original_func = aggfunc
125+
126+
def wrapped(*call_args, **call_kwargs):
127+
series = call_args[0]
128+
final_args = call_args[1:] + args
129+
final_kwargs = {**kwargs, **call_kwargs}
130+
return original_func(series, *final_args, **final_kwargs)
131+
132+
wrapped._is_wrapped = True
133+
aggfunc = wrapped
134+
return super().__new__(cls, (column, aggfunc))
135+
117136
"""
118-
Helper for column specific aggregation with control over output column names.
137+
Helper for column specific aggregation with with flexible argument passing and
138+
control over output column names.
119139
120-
Subclass of typing.NamedTuple.
140+
Subclass of tuple that wraps an aggregation function.
121141
122142
Parameters
123143
----------
@@ -126,6 +146,10 @@ class NamedAgg(NamedTuple):
126146
aggfunc : function or str
127147
Function to apply to the provided column. If string, the name of a built-in
128148
pandas function.
149+
*args : tuple, optional
150+
Positional arguments to pass to `aggfunc` when it is called.
151+
**kwargs : dict, optional
152+
Keyword arguments to pass to `aggfunc` when it is called.
129153
130154
See Also
131155
--------
@@ -141,6 +165,25 @@ class NamedAgg(NamedTuple):
141165
key
142166
1 -1 10.5
143167
2 1 12.0
168+
169+
def n_between(ser, low, high, **kwargs):
170+
return ser.between(low, high, **kwargs).sum()
171+
172+
Using positional arguments
173+
agg_between = pd.NamedAgg("a", n_between, 0, 1)
174+
df.groupby("key").agg(count_between=agg_between)
175+
count_between
176+
key
177+
1 1
178+
2 1
179+
180+
Using both positional and keyword arguments
181+
agg_between_kw = pd.NamedAgg("a", n_between, 0, 1, inclusive="both")
182+
df.groupby("key").agg(count_between_kw=agg_between_kw)
183+
count_between_kw
184+
key
185+
1 1
186+
2 1
144187
"""
145188

146189
column: Hashable

0 commit comments

Comments
 (0)