|
1 | 1 | import copy
|
| 2 | +from functools import partial |
2 | 3 | from warnings import catch_warnings
|
3 | 4 | import itertools
|
4 | 5 | import re
|
@@ -1463,9 +1464,19 @@ def equals(self, other):
|
1463 | 1464 | return False
|
1464 | 1465 | return array_equivalent(self.values, other.values)
|
1465 | 1466 |
|
1466 |
| - def _unstack(self, new_values, new_placement): |
| 1467 | + def _unstack(self, unstacker_t, new_columns): |
1467 | 1468 | """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 |
1469 | 1480 |
|
1470 | 1481 | def quantile(self, qs, interpolation='linear', axis=0, mgr=None):
|
1471 | 1482 | """
|
@@ -1710,11 +1721,21 @@ def _slice(self, slicer):
|
1710 | 1721 | def _try_cast_result(self, result, dtype=None):
|
1711 | 1722 | return result
|
1712 | 1723 |
|
1713 |
| - def _unstack(self, new_values, new_placement): |
| 1724 | + def _unstack(self, unstacker_t, new_columns): |
1714 | 1725 | # NonConsolidatable blocks can have a single item only, so we return
|
1715 | 1726 | # 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 |
1718 | 1739 |
|
1719 | 1740 |
|
1720 | 1741 | class NumericBlock(Block):
|
@@ -4171,25 +4192,32 @@ def canonicalize(block):
|
4171 | 4192 | return all(block.equals(oblock)
|
4172 | 4193 | for block, oblock in zip(self_blocks, other_blocks))
|
4173 | 4194 |
|
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) |
4177 | 4204 | new_columns = dummy.get_new_columns()
|
4178 | 4205 | new_index = dummy.get_new_index()
|
4179 | 4206 | new_blocks = []
|
4180 |
| - mask_columns = np.zeros_like(new_columns, dtype=bool) |
| 4207 | + columns_mask = [] |
4181 | 4208 |
|
4182 | 4209 | 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] |
4190 | 4219 |
|
4191 | 4220 | bm = BlockManager(new_blocks, [new_columns, new_index])
|
4192 |
| - bm = bm.take(mask_columns.nonzero()[0], axis=0) |
4193 | 4221 | return bm
|
4194 | 4222 |
|
4195 | 4223 |
|
|
0 commit comments