@@ -165,30 +165,37 @@ def apply(self, f, data, axis=0):
165
165
mutated = self .mutated
166
166
splitter = self ._get_splitter (data , axis = axis )
167
167
group_keys = self ._get_group_keys ()
168
- status = 0
168
+ reuse_result = False
169
169
result_values = []
170
170
# oh boy
171
171
f_name = com .get_callable_name (f )
172
172
if (f_name not in base .plotting_methods and
173
173
hasattr (splitter , 'fast_apply' ) and axis == 0 ):
174
174
try :
175
175
result = splitter .fast_apply (f , group_keys )
176
- result_values , mutated , status = result
177
- if status == 0 :
178
- return group_keys , result_values , mutated
176
+ fast_apply_result , mutated , successful_fast_apply = result
177
+ # If the fast apply path could be used we can return here.
178
+ # Otherwise we need to fall back to the slow implementation.
179
+ if successful_fast_apply :
180
+ return group_keys , fast_apply_result , mutated
181
+ else :
182
+ # The slow implementation can still reuse the result
183
+ # for the first group
184
+ result_values = fast_apply_result
185
+ reuse_result = True
179
186
except reduction .InvalidApply :
180
- # we detect a mutation of some kind
181
- # so take slow path
187
+ # Cannot fast apply on MultiIndex (_has_complex_internals).
188
+ # This Exception is also raised if `f` triggers an exception but
189
+ # it is preferable if the exception is raised in Python.
182
190
pass
183
191
except Exception :
184
192
# raise this error to the caller
185
193
pass
186
194
187
195
for key , (i , group ) in zip (group_keys , splitter ):
188
196
object .__setattr__ (group , 'name' , key )
189
- if status > 0 and i == 0 :
197
+ if reuse_result and i == 0 :
190
198
continue
191
-
192
199
# group might be modified
193
200
group_axes = _get_axes (group )
194
201
res = f (group )
@@ -855,7 +862,7 @@ def fast_apply(self, f, names):
855
862
starts , ends = lib .generate_slices (self .slabels , self .ngroups )
856
863
except Exception :
857
864
# fails when all -1
858
- return [], True
865
+ return [], True , False
859
866
860
867
sdata = self ._get_sorted_data ()
861
868
return reduction .apply_frame_axis0 (sdata , f , names , starts , ends )
0 commit comments