@@ -735,6 +735,17 @@ def _selection_name(self):
735
735
min max
736
736
1 1 2
737
737
2 3 4
738
+
739
+ The output column names can be controlled by passing
740
+ the desired column names and aggregations as keyword arguments.
741
+
742
+ >>> s.groupby([1, 1, 2, 2]).agg(
743
+ ... minimum='min',
744
+ ... maximum='max',
745
+ ... )
746
+ minimum maximum
747
+ 1 1 2
748
+ 2 3 4
738
749
""" )
739
750
740
751
@Appender (_apply_docs ['template' ]
@@ -749,8 +760,20 @@ def apply(self, func, *args, **kwargs):
749
760
klass = 'Series' ,
750
761
axis = '' )
751
762
@Appender (_shared_docs ['aggregate' ])
752
- def aggregate (self , func_or_funcs , * args , ** kwargs ):
763
+ def aggregate (self , func_or_funcs = None , * args , ** kwargs ):
753
764
_level = kwargs .pop ('_level' , None )
765
+
766
+ relabeling = func_or_funcs is None
767
+ columns = None
768
+ no_arg_message = ("Must provide 'func_or_funcs' or named "
769
+ "aggregation **kwargs." )
770
+ if relabeling :
771
+ columns = list (kwargs )
772
+ func_or_funcs = list (kwargs .values ())
773
+ kwargs = {}
774
+ if not columns :
775
+ raise TypeError (no_arg_message )
776
+
754
777
if isinstance (func_or_funcs , str ):
755
778
return getattr (self , func_or_funcs )(* args , ** kwargs )
756
779
@@ -759,6 +782,8 @@ def aggregate(self, func_or_funcs, *args, **kwargs):
759
782
# but not the class list / tuple itself.
760
783
ret = self ._aggregate_multiple_funcs (func_or_funcs ,
761
784
(_level or 0 ) + 1 )
785
+ if relabeling :
786
+ ret .columns = columns
762
787
else :
763
788
cyfunc = self ._is_cython_func (func_or_funcs )
764
789
if cyfunc and not args and not kwargs :
@@ -793,11 +818,14 @@ def _aggregate_multiple_funcs(self, arg, _level):
793
818
# have not shown a higher level one
794
819
# GH 15931
795
820
if isinstance (self ._selected_obj , Series ) and _level <= 1 :
796
- warnings .warn (
797
- ("using a dict on a Series for aggregation\n "
798
- "is deprecated and will be removed in a future "
799
- "version" ),
800
- FutureWarning , stacklevel = 3 )
821
+ msg = dedent ("""\
822
+ using a dict on a Series for aggregation
823
+ is deprecated and will be removed in a future version. Use \
824
+ named aggregation instead.
825
+
826
+ >>> grouper.agg(name_1=func_1, name_2=func_2)
827
+ """ )
828
+ warnings .warn (msg , FutureWarning , stacklevel = 3 )
801
829
802
830
columns = list (arg .keys ())
803
831
arg = arg .items ()
@@ -1562,7 +1590,7 @@ def groupby_series(obj, col=None):
1562
1590
1563
1591
def _is_multi_agg_with_relabel (** kwargs ):
1564
1592
"""
1565
- Check whether the kwargs pass to .agg look like multi-agg with relabling .
1593
+ Check whether kwargs passed to .agg look like multi-agg with relabeling .
1566
1594
1567
1595
Parameters
1568
1596
----------
0 commit comments