Skip to content

Commit 12f9a10

Browse files
authored
REF: unstack (#33474)
1 parent a448b97 commit 12f9a10

File tree

3 files changed

+14
-11
lines changed

3 files changed

+14
-11
lines changed

pandas/core/internals/blocks.py

+6-9
Original file line numberDiff line numberDiff line change
@@ -1384,15 +1384,13 @@ def equals(self, other) -> bool:
13841384
return False
13851385
return array_equivalent(self.values, other.values)
13861386

1387-
def _unstack(self, unstacker, new_columns, fill_value, value_columns):
1387+
def _unstack(self, unstacker, fill_value, new_placement):
13881388
"""
13891389
Return a list of unstacked blocks of self
13901390
13911391
Parameters
13921392
----------
13931393
unstacker : reshape._Unstacker
1394-
new_columns : Index
1395-
All columns of the unstacked BlockManager.
13961394
fill_value : int
13971395
Only used in ExtensionBlock._unstack
13981396
@@ -1403,17 +1401,17 @@ def _unstack(self, unstacker, new_columns, fill_value, value_columns):
14031401
mask : array_like of bool
14041402
The mask of columns of `blocks` we should keep.
14051403
"""
1406-
new_items = unstacker.get_new_columns(value_columns)
1407-
new_placement = new_columns.get_indexer(new_items)
14081404
new_values, mask = unstacker.get_new_values(
14091405
self.values.T, fill_value=fill_value
14101406
)
14111407

14121408
mask = mask.any(0)
1409+
# TODO: in all tests we have mask.all(); can we rely on that?
1410+
14131411
new_values = new_values.T[mask]
14141412
new_placement = new_placement[mask]
14151413

1416-
blocks = [make_block(new_values, placement=new_placement)]
1414+
blocks = [self.make_block_same_class(new_values, placement=new_placement)]
14171415
return blocks, mask
14181416

14191417
def quantile(self, qs, interpolation="linear", axis: int = 0):
@@ -1878,7 +1876,7 @@ def where(
18781876

18791877
return [self.make_block_same_class(result, placement=self.mgr_locs)]
18801878

1881-
def _unstack(self, unstacker, new_columns, fill_value, value_columns):
1879+
def _unstack(self, unstacker, fill_value, new_placement):
18821880
# ExtensionArray-safe unstack.
18831881
# We override ObjectBlock._unstack, which unstacks directly on the
18841882
# values of the array. For EA-backed blocks, this would require
@@ -1888,10 +1886,9 @@ def _unstack(self, unstacker, new_columns, fill_value, value_columns):
18881886
n_rows = self.shape[-1]
18891887
dummy_arr = np.arange(n_rows)
18901888

1891-
new_items = unstacker.get_new_columns(value_columns)
1892-
new_placement = new_columns.get_indexer(new_items)
18931889
new_values, mask = unstacker.get_new_values(dummy_arr, fill_value=-1)
18941890
mask = mask.any(0)
1891+
# TODO: in all tests we have mask.all(); can we rely on that?
18951892

18961893
blocks = [
18971894
self.make_block_same_class(

pandas/core/internals/managers.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1459,8 +1459,11 @@ def unstack(self, unstacker, fill_value) -> "BlockManager":
14591459

14601460
for blk in self.blocks:
14611461
blk_cols = self.items[blk.mgr_locs.indexer]
1462+
new_items = unstacker.get_new_columns(blk_cols)
1463+
new_placement = new_columns.get_indexer(new_items)
1464+
14621465
blocks, mask = blk._unstack(
1463-
unstacker, new_columns, fill_value, value_columns=blk_cols,
1466+
unstacker, fill_value, new_placement=new_placement
14641467
)
14651468

14661469
new_blocks.extend(blocks)

pandas/core/reshape/reshape.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def sorted_labels(self):
142142
indexer, to_sort = self._indexer_and_to_sort
143143
return [l.take(indexer) for l in to_sort]
144144

145-
def _make_sorted_values(self, values):
145+
def _make_sorted_values(self, values: np.ndarray) -> np.ndarray:
146146
indexer, _ = self._indexer_and_to_sort
147147

148148
sorted_values = algos.take_nd(values, indexer, axis=0)
@@ -205,6 +205,9 @@ def get_new_values(self, values, fill_value=None):
205205

206206
# we can simply reshape if we don't have a mask
207207
if mask_all and len(values):
208+
# TODO: Under what circumstances can we rely on sorted_values
209+
# matching values? When that holds, we can slice instead
210+
# of take (in particular for EAs)
208211
new_values = (
209212
sorted_values.reshape(length, width, stride)
210213
.swapaxes(1, 2)

0 commit comments

Comments
 (0)