@@ -2776,8 +2776,11 @@ def _transform_fast(self, func):
2776
2776
func = getattr (self , func )
2777
2777
2778
2778
ids , _ , ngroup = self .grouper .group_info
2779
-
2779
+ counts = self .size ().fillna (0 ).values
2780
+ cast = (counts == 0 ).any ()
2780
2781
out = algos .take_1d (func ().values , ids )
2782
+ if cast :
2783
+ out = self ._try_cast (out , self .obj )
2781
2784
return Series (out , index = self .obj .index , name = self .obj .name )
2782
2785
2783
2786
def filter (self , func , dropna = True , * args , ** kwargs ): # noqa
@@ -3456,11 +3459,21 @@ def transform(self, func, *args, **kwargs):
3456
3459
if not result .columns .equals (obj .columns ):
3457
3460
return self ._transform_general (func , * args , ** kwargs )
3458
3461
3459
- # Fast transform
3462
+ # Fast transform path for aggregations
3463
+
3464
+ # if there were groups with no observations (Categorical only?)
3465
+ # try casting data to original dtype
3466
+ counts = self .size ().fillna (0 ).values
3467
+ cast = (counts == 0 ).any ()
3468
+
3469
+ # by column (could be by block?) reshape aggregated data to
3470
+ # size of original frame by repeating obvservations with take
3460
3471
ids , _ , ngroup = self .grouper .group_info
3461
3472
out = {}
3462
3473
for col in result :
3463
3474
out [col ] = algos .take_nd (result [col ].values , ids )
3475
+ if cast :
3476
+ out [col ] = self ._try_cast (out [col ], obj [col ])
3464
3477
3465
3478
return DataFrame (out , columns = result .columns , index = obj .index )
3466
3479
0 commit comments