@@ -2336,10 +2336,13 @@ def result_index(self):
2336
2336
if not self .compressed and len (self .groupings ) == 1 :
2337
2337
return self .groupings [0 ].group_index .rename (self .names [0 ])
2338
2338
2339
- return MultiIndex (levels = [ping .group_index for ping in self .groupings ],
2340
- labels = self .recons_labels ,
2341
- verify_integrity = False ,
2342
- names = self .names )
2339
+ labels = self .recons_labels
2340
+ levels = [ping .group_index for ping in self .groupings ]
2341
+ result = MultiIndex (levels = levels ,
2342
+ labels = labels ,
2343
+ verify_integrity = False ,
2344
+ names = self .names )
2345
+ return result .remove_unused_levels ()
2343
2346
2344
2347
def get_group_levels (self ):
2345
2348
if not self .compressed and len (self .groupings ) == 1 :
@@ -4151,7 +4154,7 @@ def first_not_none(values):
4151
4154
not_indexed_same = not_indexed_same )
4152
4155
elif self .grouper .groupings is not None :
4153
4156
if len (self .grouper .groupings ) > 1 :
4154
- key_index = MultiIndex . from_tuples ( keys , names = key_names )
4157
+ key_index = self . grouper . result_index
4155
4158
4156
4159
else :
4157
4160
ping = self .grouper .groupings [0 ]
@@ -4241,8 +4244,9 @@ def first_not_none(values):
4241
4244
4242
4245
# normally use vstack as its faster than concat
4243
4246
# and if we have mi-columns
4244
- if isinstance (v .index ,
4245
- MultiIndex ) or key_index is None :
4247
+ if (isinstance (v .index , MultiIndex ) or
4248
+ key_index is None or
4249
+ isinstance (key_index , MultiIndex )):
4246
4250
stacked_values = np .vstack (map (np .asarray , values ))
4247
4251
result = DataFrame (stacked_values , index = key_index ,
4248
4252
columns = index )
@@ -4280,7 +4284,7 @@ def first_not_none(values):
4280
4284
else :
4281
4285
result = result ._convert (datetime = True )
4282
4286
4283
- return self . _reindex_output ( result )
4287
+ return result
4284
4288
4285
4289
# values are not series or array-like but scalars
4286
4290
else :
@@ -4661,7 +4665,7 @@ def _wrap_aggregated_output(self, output, names=None):
4661
4665
if self .axis == 1 :
4662
4666
result = result .T
4663
4667
4664
- return self . _reindex_output ( result ) ._convert (datetime = True )
4668
+ return result ._convert (datetime = True )
4665
4669
4666
4670
def _wrap_transformed_output (self , output , names = None ):
4667
4671
return DataFrame (output , index = self .obj .index )
@@ -4682,60 +4686,7 @@ def _wrap_agged_blocks(self, items, blocks):
4682
4686
if self .axis == 1 :
4683
4687
result = result .T
4684
4688
4685
- return self ._reindex_output (result )._convert (datetime = True )
4686
-
4687
- def _reindex_output (self , result ):
4688
- """
4689
- if we have categorical groupers, then we want to make sure that
4690
- we have a fully reindex-output to the levels. These may have not
4691
- participated in the groupings (e.g. may have all been
4692
- nan groups)
4693
-
4694
- This can re-expand the output space
4695
- """
4696
- groupings = self .grouper .groupings
4697
- if groupings is None :
4698
- return result
4699
- elif len (groupings ) == 1 :
4700
- return result
4701
- elif not any (isinstance (ping .grouper , (Categorical , CategoricalIndex ))
4702
- for ping in groupings ):
4703
- return result
4704
-
4705
- levels_list = [ping .group_index for ping in groupings ]
4706
- index , _ = MultiIndex .from_product (
4707
- levels_list , names = self .grouper .names ).sortlevel ()
4708
-
4709
- if self .as_index :
4710
- d = {self .obj ._get_axis_name (self .axis ): index , 'copy' : False }
4711
- return result .reindex (** d )
4712
-
4713
- # GH 13204
4714
- # Here, the categorical in-axis groupers, which need to be fully
4715
- # expanded, are columns in `result`. An idea is to do:
4716
- # result = result.set_index(self.grouper.names)
4717
- # .reindex(index).reset_index()
4718
- # but special care has to be taken because of possible not-in-axis
4719
- # groupers.
4720
- # So, we manually select and drop the in-axis grouper columns,
4721
- # reindex `result`, and then reset the in-axis grouper columns.
4722
-
4723
- # Select in-axis groupers
4724
- in_axis_grps = [(i , ping .name ) for (i , ping )
4725
- in enumerate (groupings ) if ping .in_axis ]
4726
- g_nums , g_names = zip (* in_axis_grps )
4727
-
4728
- result = result .drop (labels = list (g_names ), axis = 1 )
4729
-
4730
- # Set a temp index and reindex (possibly expanding)
4731
- result = result .set_index (self .grouper .result_index
4732
- ).reindex (index , copy = False )
4733
-
4734
- # Reset in-axis grouper columns
4735
- # (using level numbers `g_nums` because level names may not be unique)
4736
- result = result .reset_index (level = g_nums )
4737
-
4738
- return result .reset_index (drop = True )
4689
+ return result ._convert (datetime = True )
4739
4690
4740
4691
def _iterate_column_groupbys (self ):
4741
4692
for i , colname in enumerate (self ._selected_obj .columns ):
0 commit comments