Skip to content

Commit fcba171

Browse files
committed
Move more code from BlockManager.unstack to Block._unstack
1 parent 1cec0f3 commit fcba171

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
@@ -1463,9 +1464,19 @@ def equals(self, other):
14631464
return False
14641465
return array_equivalent(self.values, other.values)
14651466

1466-
def _unstack(self, new_values, new_placement):
1467+
def _unstack(self, unstacker_t, new_columns):
14671468
"""Return a list of unstacked blocks of self"""
1468-
return [make_block(new_values, placement=new_placement)]
1469+
unstacker = unstacker_t(self.values.T)
1470+
new_items = unstacker.get_new_columns()
1471+
new_placement = new_columns.get_indexer(new_items)
1472+
new_values, mask = unstacker.get_new_values()
1473+
1474+
mask = mask.any(0)
1475+
new_values = new_values.T[mask]
1476+
new_placement = new_placement[mask]
1477+
1478+
blocks = [make_block(new_values, placement=new_placement)]
1479+
return blocks, mask
14691480

14701481
def quantile(self, qs, interpolation='linear', axis=0, mgr=None):
14711482
"""
@@ -1710,11 +1721,21 @@ def _slice(self, slicer):
17101721
def _try_cast_result(self, result, dtype=None):
17111722
return result
17121723

1713-
def _unstack(self, new_values, new_placement):
1724+
def _unstack(self, unstacker_t, new_columns):
17141725
# NonConsolidatable blocks can have a single item only, so we return
17151726
# one block per item
1716-
return [self.make_block_same_class(vals, [place])
1717-
for vals, place in zip(new_values, new_placement)]
1727+
unstacker = unstacker_t(self.values.T)
1728+
new_items = unstacker.get_new_columns()
1729+
new_placement = new_columns.get_indexer(new_items)
1730+
new_values, mask = unstacker.get_new_values()
1731+
1732+
mask = mask.any(0)
1733+
new_values = new_values.T[mask]
1734+
new_placement = new_placement[mask]
1735+
1736+
blocks = [self.make_block_same_class(vals, [place])
1737+
for vals, place in zip(new_values, new_placement)]
1738+
return blocks, mask
17181739

17191740

17201741
class NumericBlock(Block):
@@ -4171,25 +4192,32 @@ def canonicalize(block):
41714192
return all(block.equals(oblock)
41724193
for block, oblock in zip(self_blocks, other_blocks))
41734194

4174-
def unstack(self, unstacker):
4175-
"""Return blockmanager with all blocks unstacked"""
4176-
dummy = unstacker(np.empty((0, 0)), value_columns=self.items)
4195+
def unstack(self, unstacker_t):
4196+
"""Return a blockmanager with all blocks unstacked.
4197+
4198+
Parameters
4199+
----------
4200+
unstacker_t : type
4201+
A (partially-applied) ``pd.core.reshape._Unstacker`` class.
4202+
"""
4203+
dummy = unstacker_t(np.empty((0, 0)), value_columns=self.items)
41774204
new_columns = dummy.get_new_columns()
41784205
new_index = dummy.get_new_index()
41794206
new_blocks = []
4180-
mask_columns = np.zeros_like(new_columns, dtype=bool)
4207+
columns_mask = []
41814208

41824209
for blk in self.blocks:
4183-
bunstacker = unstacker(
4184-
blk.values.T, value_columns=self.items[blk.mgr_locs.indexer])
4185-
new_items = bunstacker.get_new_columns()
4186-
new_values, mask = bunstacker.get_new_values()
4187-
new_placement = new_columns.get_indexer(new_items)
4188-
mask_columns[new_placement] = mask.any(0)
4189-
new_blocks.extend(blk._unstack(new_values.T, new_placement))
4210+
blocks, mask = blk._unstack(
4211+
partial(unstacker_t,
4212+
value_columns=self.items[blk.mgr_locs.indexer]),
4213+
new_columns)
4214+
4215+
new_blocks.extend(blocks)
4216+
columns_mask.extend(mask)
4217+
4218+
new_columns = new_columns[columns_mask]
41904219

41914220
bm = BlockManager(new_blocks, [new_columns, new_index])
4192-
bm = bm.take(mask_columns.nonzero()[0], axis=0)
41934221
return bm
41944222

41954223

0 commit comments

Comments
 (0)