Skip to content

Commit 82edc0f

Browse files
committed
Move more code from BlockManager.unstack to Block._unstack
1 parent ff353ef commit 82edc0f

File tree

1 file changed

+45
-17
lines changed

1 file changed

+45
-17
lines changed

pandas/core/internals.py

+45-17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import copy
2+
from functools import partial
23
from warnings import catch_warnings
34
import itertools
45
import re
@@ -1467,9 +1468,19 @@ def equals(self, other):
14671468
return False
14681469
return array_equivalent(self.values, other.values)
14691470

1470-
def _unstack(self, new_values, new_placement):
1471+
def _unstack(self, unstacker_t, new_columns):
14711472
"""Return a list of unstacked blocks of self"""
1472-
return [make_block(new_values, placement=new_placement)]
1473+
unstacker = unstacker_t(self.values.T)
1474+
new_items = unstacker.get_new_columns()
1475+
new_placement = new_columns.get_indexer(new_items)
1476+
new_values, mask = unstacker.get_new_values()
1477+
1478+
mask = mask.any(0)
1479+
new_values = new_values.T[mask]
1480+
new_placement = new_placement[mask]
1481+
1482+
blocks = [make_block(new_values, placement=new_placement)]
1483+
return blocks, mask
14731484

14741485
def quantile(self, qs, interpolation='linear', axis=0, mgr=None):
14751486
"""
@@ -1707,11 +1718,21 @@ def _slice(self, slicer):
17071718
def _try_cast_result(self, result, dtype=None):
17081719
return result
17091720

1710-
def _unstack(self, new_values, new_placement):
1721+
def _unstack(self, unstacker_t, new_columns):
17111722
# NonConsolidatable blocks can have a single item only, so we return
17121723
# one block per item
1713-
return [self.make_block_same_class(vals, [place])
1714-
for vals, place in zip(new_values, new_placement)]
1724+
unstacker = unstacker_t(self.values.T)
1725+
new_items = unstacker.get_new_columns()
1726+
new_placement = new_columns.get_indexer(new_items)
1727+
new_values, mask = unstacker.get_new_values()
1728+
1729+
mask = mask.any(0)
1730+
new_values = new_values.T[mask]
1731+
new_placement = new_placement[mask]
1732+
1733+
blocks = [self.make_block_same_class(vals, [place])
1734+
for vals, place in zip(new_values, new_placement)]
1735+
return blocks, mask
17151736

17161737

17171738
class NumericBlock(Block):
@@ -4168,25 +4189,32 @@ def canonicalize(block):
41684189
return all(block.equals(oblock)
41694190
for block, oblock in zip(self_blocks, other_blocks))
41704191

4171-
def unstack(self, unstacker):
4172-
"""Return blockmanager with all blocks unstacked"""
4173-
dummy = unstacker(np.empty((0, 0)), value_columns=self.items)
4192+
def unstack(self, unstacker_t):
4193+
"""Return a blockmanager with all blocks unstacked.
4194+
4195+
Parameters
4196+
----------
4197+
unstacker_t : type
4198+
A (partially-applied) ``pd.core.reshape._Unstacker`` class.
4199+
"""
4200+
dummy = unstacker_t(np.empty((0, 0)), value_columns=self.items)
41744201
new_columns = dummy.get_new_columns()
41754202
new_index = dummy.get_new_index()
41764203
new_blocks = []
4177-
mask_columns = np.zeros_like(new_columns, dtype=bool)
4204+
columns_mask = []
41784205

41794206
for blk in self.blocks:
4180-
bunstacker = unstacker(
4181-
blk.values.T, value_columns=self.items[blk.mgr_locs.indexer])
4182-
new_items = bunstacker.get_new_columns()
4183-
new_values, mask = bunstacker.get_new_values()
4184-
new_placement = new_columns.get_indexer(new_items)
4185-
mask_columns[new_placement] = mask.any(0)
4186-
new_blocks.extend(blk._unstack(new_values.T, new_placement))
4207+
blocks, mask = blk._unstack(
4208+
partial(unstacker_t,
4209+
value_columns=self.items[blk.mgr_locs.indexer]),
4210+
new_columns)
4211+
4212+
new_blocks.extend(blocks)
4213+
columns_mask.extend(mask)
4214+
4215+
new_columns = new_columns[columns_mask]
41874216

41884217
bm = BlockManager(new_blocks, [new_columns, new_index])
4189-
bm = bm.take(mask_columns.nonzero()[0], axis=0)
41904218
return bm
41914219

41924220

0 commit comments

Comments
 (0)