@@ -137,14 +137,6 @@ def f(x):
137
137
self .orig_f : AggFuncType = func
138
138
self .f : AggFuncType = f
139
139
140
- @property
141
- def index (self ) -> Index :
142
- return self .obj .index
143
-
144
- @property
145
- def agg_axis (self ) -> Index :
146
- return self .obj ._get_agg_axis (self .axis )
147
-
148
140
@abc .abstractmethod
149
141
def apply (self ) -> FrameOrSeriesUnion :
150
142
pass
@@ -163,9 +155,8 @@ def agg(self) -> FrameOrSeriesUnion | None:
163
155
args = self .args
164
156
kwargs = self .kwargs
165
157
166
- result = self .maybe_apply_str ()
167
- if result is not None :
168
- return result
158
+ if isinstance (arg , str ):
159
+ return self .maybe_apply_str ()
169
160
170
161
if is_dict_like (arg ):
171
162
return self .agg_dict_like ()
@@ -465,27 +456,20 @@ def agg_dict_like(self) -> FrameOrSeriesUnion:
465
456
466
457
return result
467
458
468
- def maybe_apply_str (self ) -> FrameOrSeriesUnion | None :
459
+ def maybe_apply_str (self ) -> FrameOrSeriesUnion :
469
460
"""
470
461
Compute apply in case of a string.
471
462
472
463
Returns
473
464
-------
474
- result: Series, DataFrame, or None
475
- Result when self.f is a string, None otherwise.
465
+ result: Series or DataFrame
476
466
"""
467
+ # Caller is responsible for checking isinstance(self.f, str)
477
468
f = self .f
478
- if not isinstance (f , str ):
479
- return None
469
+ f = cast (str , f )
480
470
481
471
obj = self .obj
482
472
483
- # TODO: GH 39993 - Avoid special-casing by replacing with lambda
484
- if f == "size" and isinstance (obj , ABCDataFrame ):
485
- # Special-cased because DataFrame.size returns a single scalar
486
- value = obj .shape [self .axis ]
487
- return obj ._constructor_sliced (value , index = self .agg_axis , name = "size" )
488
-
489
473
# Support for `frame.transform('method')`
490
474
# Some methods (shift, etc.) require the axis argument, others
491
475
# don't, so inspect and insert if necessary.
@@ -587,7 +571,22 @@ def _try_aggregate_string_function(self, obj, arg: str, *args, **kwargs):
587
571
)
588
572
589
573
590
- class FrameApply (Apply ):
574
+ class NDFrameApply (Apply ):
575
+ """
576
+ Methods shared by FrameApply and SeriesApply but
577
+ not GroupByApply or ResamplerWindowApply
578
+ """
579
+
580
+ @property
581
+ def index (self ) -> Index :
582
+ return self .obj .index
583
+
584
+ @property
585
+ def agg_axis (self ) -> Index :
586
+ return self .obj ._get_agg_axis (self .axis )
587
+
588
+
589
+ class FrameApply (NDFrameApply ):
591
590
obj : DataFrame
592
591
593
592
# ---------------------------------------------------------------
@@ -644,9 +643,8 @@ def apply(self) -> FrameOrSeriesUnion:
644
643
return self .apply_empty_result ()
645
644
646
645
# string dispatch
647
- result = self .maybe_apply_str ()
648
- if result is not None :
649
- return result
646
+ if isinstance (self .f , str ):
647
+ return self .maybe_apply_str ()
650
648
651
649
# ufunc
652
650
elif isinstance (self .f , np .ufunc ):
@@ -831,6 +829,16 @@ def wrap_results(self, results: ResType, res_index: Index) -> FrameOrSeriesUnion
831
829
832
830
return result
833
831
832
+ def maybe_apply_str (self ) -> FrameOrSeriesUnion :
833
+ # Caller is responsible for checking isinstance(self.f, str)
834
+ # TODO: GH#39993 - Avoid special-casing by replacing with lambda
835
+ if self .f == "size" :
836
+ # Special-cased because DataFrame.size returns a single scalar
837
+ obj = self .obj
838
+ value = obj .shape [self .axis ]
839
+ return obj ._constructor_sliced (value , index = self .agg_axis , name = "size" )
840
+ return super ().maybe_apply_str ()
841
+
834
842
835
843
class FrameRowApply (FrameApply ):
836
844
axis = 0
@@ -967,7 +975,7 @@ def infer_to_same_shape(self, results: ResType, res_index: Index) -> DataFrame:
967
975
return result
968
976
969
977
970
- class SeriesApply (Apply ):
978
+ class SeriesApply (NDFrameApply ):
971
979
obj : Series
972
980
axis = 0
973
981
@@ -1001,10 +1009,9 @@ def apply(self) -> FrameOrSeriesUnion:
1001
1009
if result is not None :
1002
1010
return result
1003
1011
1004
- # if we are a string, try to dispatch
1005
- result = self .maybe_apply_str ()
1006
- if result is not None :
1007
- return result
1012
+ if isinstance (self .f , str ):
1013
+ # if we are a string, try to dispatch
1014
+ return self .maybe_apply_str ()
1008
1015
1009
1016
return self .apply_standard ()
1010
1017
0 commit comments