|
1 | 1 | import copy
|
| 2 | +from functools import partial |
2 | 3 | from warnings import catch_warnings
|
3 | 4 | import itertools
|
4 | 5 | import re
|
@@ -1467,9 +1468,19 @@ def equals(self, other):
|
1467 | 1468 | return False
|
1468 | 1469 | return array_equivalent(self.values, other.values)
|
1469 | 1470 |
|
1470 |
| - def _unstack(self, new_values, new_placement): |
| 1471 | + def _unstack(self, unstacker_t, new_columns): |
1471 | 1472 | """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 |
1473 | 1484 |
|
1474 | 1485 | def quantile(self, qs, interpolation='linear', axis=0, mgr=None):
|
1475 | 1486 | """
|
@@ -1707,11 +1718,21 @@ def _slice(self, slicer):
|
1707 | 1718 | def _try_cast_result(self, result, dtype=None):
|
1708 | 1719 | return result
|
1709 | 1720 |
|
1710 |
| - def _unstack(self, new_values, new_placement): |
| 1721 | + def _unstack(self, unstacker_t, new_columns): |
1711 | 1722 | # NonConsolidatable blocks can have a single item only, so we return
|
1712 | 1723 | # 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 |
1715 | 1736 |
|
1716 | 1737 |
|
1717 | 1738 | class NumericBlock(Block):
|
@@ -4168,25 +4189,32 @@ def canonicalize(block):
|
4168 | 4189 | return all(block.equals(oblock)
|
4169 | 4190 | for block, oblock in zip(self_blocks, other_blocks))
|
4170 | 4191 |
|
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) |
4174 | 4201 | new_columns = dummy.get_new_columns()
|
4175 | 4202 | new_index = dummy.get_new_index()
|
4176 | 4203 | new_blocks = []
|
4177 |
| - mask_columns = np.zeros_like(new_columns, dtype=bool) |
| 4204 | + columns_mask = [] |
4178 | 4205 |
|
4179 | 4206 | 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] |
4187 | 4216 |
|
4188 | 4217 | bm = BlockManager(new_blocks, [new_columns, new_index])
|
4189 |
| - bm = bm.take(mask_columns.nonzero()[0], axis=0) |
4190 | 4218 | return bm
|
4191 | 4219 |
|
4192 | 4220 |
|
|
0 commit comments