@@ -491,7 +491,7 @@ def _set_result_index_ordered(self, result):
491
491
492
492
# shortcut of we have an already ordered grouper
493
493
if not self .grouper .is_monotonic :
494
- index = Index (np .concatenate ([ indices [v ] for v in self .grouper .result_index ]))
494
+ index = Index (np .concatenate ([ indices [v ] for v in self .grouper .result_index if v in indices ]))
495
495
result .index = index
496
496
result = result .sort_index ()
497
497
@@ -2436,6 +2436,8 @@ def transform(self, func, *args, **kwargs):
2436
2436
2437
2437
wrapper = lambda x : func (x , * args , ** kwargs )
2438
2438
for i , (name , group ) in enumerate (self ):
2439
+ if name not in self .indices :
2440
+ continue
2439
2441
2440
2442
object .__setattr__ (group , 'name' , name )
2441
2443
res = wrapper (group )
@@ -2451,7 +2453,7 @@ def transform(self, func, *args, **kwargs):
2451
2453
except :
2452
2454
pass
2453
2455
2454
- indexer = self ._get_index ( name )
2456
+ indexer = self .indices [ name ]
2455
2457
result [indexer ] = res
2456
2458
2457
2459
result = _possibly_downcast_to_dtype (result , dtype )
@@ -2465,9 +2467,12 @@ def _transform_fast(self, func):
2465
2467
"""
2466
2468
if isinstance (func , compat .string_types ):
2467
2469
func = getattr (self ,func )
2470
+
2468
2471
values = func ().values
2469
- counts = self .size ().values
2472
+ counts = self .size ().fillna ( 0 ). values
2470
2473
values = np .repeat (values , com ._ensure_platform_int (counts ))
2474
+ if any (counts == 0 ):
2475
+ values = self ._try_cast (values , self ._selected_obj )
2471
2476
2472
2477
return self ._set_result_index_ordered (Series (values ))
2473
2478
@@ -2502,8 +2507,11 @@ def true_and_notnull(x, *args, **kwargs):
2502
2507
return b and notnull (b )
2503
2508
2504
2509
try :
2505
- indices = [self ._get_index (name ) if true_and_notnull (group ) else []
2506
- for name , group in self ]
2510
+ indices = []
2511
+ for name , group in self :
2512
+ if true_and_notnull (group ) and name in self .indices :
2513
+ indices .append (self .indices [name ])
2514
+
2507
2515
except ValueError :
2508
2516
raise TypeError ("the filter must return a boolean result" )
2509
2517
except TypeError :
@@ -3015,24 +3023,18 @@ def transform(self, func, *args, **kwargs):
3015
3023
if not result .columns .equals (obj .columns ):
3016
3024
return self ._transform_general (func , * args , ** kwargs )
3017
3025
3018
- # a grouped that doesn't preserve the index, remap index based on the grouper
3019
- # and broadcast it
3020
- if ((not isinstance (obj .index ,MultiIndex ) and
3021
- type (result .index ) != type (obj .index )) or
3022
- len (result .index ) != len (obj .index )):
3023
- results = np .empty_like (obj .values , result .values .dtype )
3024
- indices = self .indices
3025
- for (name , group ), (i , row ) in zip (self , result .iterrows ()):
3026
+ results = np .empty_like (obj .values , result .values .dtype )
3027
+ indices = self .indices
3028
+ for (name , group ), (i , row ) in zip (self , result .iterrows ()):
3029
+ if name in indices :
3026
3030
indexer = indices [name ]
3027
3031
results [indexer ] = np .tile (row .values ,len (indexer )).reshape (len (indexer ),- 1 )
3028
- return DataFrame (results ,columns = result .columns ,index = obj .index ).convert_objects ()
3029
3032
3030
- # we can merge the result in
3031
- # GH 7383
3032
- names = result .columns
3033
- result = obj .merge (result , how = 'outer' , left_index = True , right_index = True ).iloc [:,- result .shape [1 ]:]
3034
- result .columns = names
3035
- return result
3033
+ counts = self .size ().fillna (0 ).values
3034
+ if any (counts == 0 ):
3035
+ results = self ._try_cast (results , obj [result .columns ])
3036
+
3037
+ return DataFrame (results ,columns = result .columns ,index = obj .index ).convert_objects ()
3036
3038
3037
3039
def _define_paths (self , func , * args , ** kwargs ):
3038
3040
if isinstance (func , compat .string_types ):
@@ -3126,8 +3128,8 @@ def filter(self, func, dropna=True, *args, **kwargs):
3126
3128
# interpret the result of the filter
3127
3129
if (isinstance (res , (bool , np .bool_ )) or
3128
3130
np .isscalar (res ) and isnull (res )):
3129
- if res and notnull (res ):
3130
- indices .append (self ._get_index ( name ) )
3131
+ if res and notnull (res ) and name in self . indices :
3132
+ indices .append (self .indices [ name ] )
3131
3133
else :
3132
3134
# non scalars aren't allowed
3133
3135
raise TypeError ("filter function returned a %s, "
0 commit comments