@@ -209,37 +209,52 @@ def _unstack_multiple(data, clocs):
209
209
210
210
index = data .index
211
211
212
- clevels , rlevels = _partition (index .levels , clocs )
213
- clabels , rlabels = _partition (index .labels , clocs )
214
- cnames , rnames = _partition (index .names , clocs )
212
+ clocs = [index ._get_level_number (i ) for i in clocs ]
213
+
214
+ rlocs = [i for i in range (index .nlevels ) if i not in clocs ]
215
+
216
+ clevels = [index .levels [i ] for i in clocs ]
217
+ clabels = [index .labels [i ] for i in clocs ]
218
+ cnames = [index .names [i ] for i in clocs ]
219
+ rlevels = [index .levels [i ] for i in rlocs ]
220
+ rlabels = [index .labels [i ] for i in rlocs ]
221
+ rnames = [index .names [i ] for i in rlocs ]
215
222
216
223
shape = [len (x ) for x in clevels ]
217
224
group_index = get_group_index (clabels , shape )
218
225
219
226
comp_ids , obs_ids = _compress_group_index (group_index , sort = False )
227
+ recons_labels = decons_group_index (obs_ids , shape )
220
228
221
229
dummy_index = MultiIndex (levels = rlevels + [obs_ids ],
222
230
labels = rlabels + [comp_ids ],
223
231
names = rnames + ['__placeholder__' ])
224
232
225
- dummy = DataFrame (data .values , index = dummy_index ,
226
- columns = data .columns )
227
-
228
- unstacked = dummy .unstack ('__placeholder__' )
229
-
230
- if isinstance (unstacked , Series ):
231
- unstcols = unstacked .index
233
+ if isinstance (data , Series ):
234
+ dummy = Series (data .values , index = dummy_index )
235
+ unstacked = dummy .unstack ('__placeholder__' )
236
+ new_levels = clevels
237
+ new_names = cnames
238
+ new_labels = recons_labels
232
239
else :
233
- unstcols = unstacked .columns
240
+ if isinstance (data .columns , MultiIndex ):
241
+ raise NotImplementedError ('Unstacking multiple levels with '
242
+ 'hierarchical columns not yet supported' )
234
243
235
- new_levels = [ unstcols . levels [ 0 ]] + clevels
236
- new_names = [ data .columns . name ] + cnames
244
+ dummy = DataFrame ( data . values , index = dummy_index ,
245
+ columns = data .columns )
237
246
238
- recons_labels = decons_group_index (obs_ids , shape )
247
+ unstacked = dummy .unstack ('__placeholder__' )
248
+ if isinstance (unstacked , Series ):
249
+ unstcols = unstacked .index
250
+ else :
251
+ unstcols = unstacked .columns
252
+ new_levels = [unstcols .levels [0 ]] + clevels
253
+ new_names = [data .columns .name ] + cnames
239
254
240
- new_labels = [unstcols .labels [0 ]]
241
- for rec in recons_labels :
242
- new_labels .append (rec .take (unstcols .labels [- 1 ]))
255
+ new_labels = [unstcols .labels [0 ]]
256
+ for rec in recons_labels :
257
+ new_labels .append (rec .take (unstcols .labels [- 1 ]))
243
258
244
259
new_columns = MultiIndex (levels = new_levels , labels = new_labels ,
245
260
names = new_names )
@@ -251,22 +266,6 @@ def _unstack_multiple(data, clocs):
251
266
252
267
return unstacked
253
268
254
-
255
- def _partition (values , inds ):
256
- left = []
257
- right = []
258
-
259
- set_inds = set (inds )
260
-
261
- for i , val in enumerate (values ):
262
- if i in set_inds :
263
- left .append (val )
264
- else :
265
- right .append (val )
266
-
267
- return left , right
268
-
269
-
270
269
def pivot (self , index = None , columns = None , values = None ):
271
270
"""
272
271
See DataFrame.pivot
@@ -351,6 +350,9 @@ def _slow_pivot(index, columns, values):
351
350
return DataFrame (tree )
352
351
353
352
def unstack (obj , level ):
353
+ if isinstance (level , (tuple , list )):
354
+ return _unstack_multiple (obj , level )
355
+
354
356
if isinstance (obj , DataFrame ):
355
357
if isinstance (obj .index , MultiIndex ):
356
358
return _unstack_frame (obj , level )
0 commit comments