@@ -1484,9 +1484,19 @@ def equals(self, other):
1484
1484
return False
1485
1485
return array_equivalent (self .values , other .values )
1486
1486
1487
- def _unstack (self , new_values , new_placement ):
1487
+ def _unstack (self , unstacker_t , new_columns ):
1488
1488
"""Return a list of unstacked blocks of self"""
1489
- return [make_block (new_values , placement = new_placement )]
1489
+ unstacker = unstacker_t (self .values .T )
1490
+ new_items = unstacker .get_new_columns ()
1491
+ new_placement = new_columns .get_indexer (new_items )
1492
+ new_values , mask = unstacker .get_new_values ()
1493
+
1494
+ mask = mask .any (0 )
1495
+ new_values = new_values .T [mask ]
1496
+ new_placement = new_placement [mask ]
1497
+
1498
+ blocks = [make_block (new_values , placement = new_placement )]
1499
+ return blocks , mask
1490
1500
1491
1501
def quantile (self , qs , interpolation = 'linear' , axis = 0 , mgr = None ):
1492
1502
"""
@@ -1716,11 +1726,21 @@ def _slice(self, slicer):
1716
1726
def _try_cast_result (self , result , dtype = None ):
1717
1727
return result
1718
1728
1719
- def _unstack (self , new_values , new_placement ):
1729
+ def _unstack (self , unstacker_t , new_columns ):
1720
1730
# NonConsolidatable blocks can have a single item only, so we return
1721
1731
# one block per item
1722
- return [self .make_block_same_class (vals , [place ])
1723
- for vals , place in zip (new_values , new_placement )]
1732
+ unstacker = unstacker_t (self .values .T )
1733
+ new_items = unstacker .get_new_columns ()
1734
+ new_placement = new_columns .get_indexer (new_items )
1735
+ new_values , mask = unstacker .get_new_values ()
1736
+
1737
+ mask = mask .any (0 )
1738
+ new_values = new_values .T [mask ]
1739
+ new_placement = new_placement [mask ]
1740
+
1741
+ blocks = [self .make_block_same_class (vals , [place ])
1742
+ for vals , place in zip (new_values , new_placement )]
1743
+ return blocks , mask
1724
1744
1725
1745
1726
1746
class NumericBlock (Block ):
@@ -4177,25 +4197,32 @@ def canonicalize(block):
4177
4197
return all (block .equals (oblock )
4178
4198
for block , oblock in zip (self_blocks , other_blocks ))
4179
4199
4180
- def unstack (self , unstacker ):
4181
- """Return blockmanager with all blocks unstacked"""
4182
- dummy = unstacker (np .empty ((0 , 0 )), value_columns = self .items )
4200
+ def unstack (self , unstacker_t ):
4201
+ """Return a blockmanager with all blocks unstacked.
4202
+
4203
+ Parameters
4204
+ ----------
4205
+ unstacker_t : type
4206
+ A (partially-applied) ``pd.core.reshape._Unstacker`` class.
4207
+ """
4208
+ dummy = unstacker_t (np .empty ((0 , 0 )), value_columns = self .items )
4183
4209
new_columns = dummy .get_new_columns ()
4184
4210
new_index = dummy .get_new_index ()
4185
4211
new_blocks = []
4186
- mask_columns = np . zeros_like ( new_columns , dtype = bool )
4212
+ columns_mask = []
4187
4213
4188
4214
for blk in self .blocks :
4189
- bunstacker = unstacker (
4190
- blk .values .T , value_columns = self .items [blk .mgr_locs .indexer ])
4191
- new_items = bunstacker .get_new_columns ()
4192
- new_values , mask = bunstacker .get_new_values ()
4193
- new_placement = new_columns .get_indexer (new_items )
4194
- mask_columns [new_placement ] = mask .any (0 )
4195
- new_blocks .extend (blk ._unstack (new_values .T , new_placement ))
4215
+ blocks , mask = blk ._unstack (
4216
+ partial (unstacker_t ,
4217
+ value_columns = self .items [blk .mgr_locs .indexer ]),
4218
+ new_columns )
4219
+
4220
+ new_blocks .extend (blocks )
4221
+ columns_mask .extend (mask )
4222
+
4223
+ new_columns = new_columns [columns_mask ]
4196
4224
4197
4225
bm = BlockManager (new_blocks , [new_columns , new_index ])
4198
- bm = bm .take (mask_columns .nonzero ()[0 ], axis = 0 )
4199
4226
return bm
4200
4227
4201
4228
0 commit comments