Skip to content

Commit 804b8e5

Browse files
jbrockmendeldebnathshoham
authored andcommitted
PERF: unstack (#42704)
1 parent 90bd817 commit 804b8e5

File tree

3 files changed

+11
-5
lines changed

3 files changed

+11
-5
lines changed

asv_bench/benchmarks/reshape.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def setup(self, dtype):
111111
values = np.take(list(string.ascii_letters), indices)
112112
values = [pd.Categorical(v) for v in values.T]
113113

114-
self.df = DataFrame(values, index, columns)
114+
self.df = DataFrame({i: cat for i, cat in enumerate(values)}, index, columns)
115115
self.df2 = self.df.iloc[:-1]
116116

117117
def time_full_product(self, dtype):

pandas/core/internals/blocks.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,7 @@ def where(self, other, cond, errors="raise") -> list[Block]:
12551255

12561256
return result_blocks
12571257

1258-
def _unstack(self, unstacker, fill_value, new_placement):
1258+
def _unstack(self, unstacker, fill_value, new_placement, allow_fill: bool):
12591259
"""
12601260
Return a list of unstacked blocks of self
12611261
@@ -1264,6 +1264,7 @@ def _unstack(self, unstacker, fill_value, new_placement):
12641264
unstacker : reshape._Unstacker
12651265
fill_value : int
12661266
Only used in ExtensionBlock._unstack
1267+
allow_fill : bool
12671268
12681269
Returns
12691270
-------
@@ -1638,7 +1639,7 @@ def where(self, other, cond, errors="raise") -> list[Block]:
16381639

16391640
return [self.make_block_same_class(result)]
16401641

1641-
def _unstack(self, unstacker, fill_value, new_placement):
1642+
def _unstack(self, unstacker, fill_value, new_placement, allow_fill: bool):
16421643
# ExtensionArray-safe unstack.
16431644
# We override ObjectBlock._unstack, which unstacks directly on the
16441645
# values of the array. For EA-backed blocks, this would require
@@ -1655,7 +1656,7 @@ def _unstack(self, unstacker, fill_value, new_placement):
16551656
blocks = [
16561657
# TODO: could cast to object depending on fill_value?
16571658
self.make_block_same_class(
1658-
self.values.take(indices, allow_fill=True, fill_value=fill_value),
1659+
self.values.take(indices, allow_fill=allow_fill, fill_value=fill_value),
16591660
BlockPlacement(place),
16601661
)
16611662
for indices, place in zip(new_values.T, new_placement)

pandas/core/internals/managers.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -1368,6 +1368,8 @@ def unstack(self, unstacker, fill_value) -> BlockManager:
13681368
new_columns = unstacker.get_new_columns(self.items)
13691369
new_index = unstacker.new_index
13701370

1371+
allow_fill = not unstacker.mask.all()
1372+
13711373
new_blocks: list[Block] = []
13721374
columns_mask: list[np.ndarray] = []
13731375

@@ -1377,7 +1379,10 @@ def unstack(self, unstacker, fill_value) -> BlockManager:
13771379
new_placement = new_columns.get_indexer(new_items)
13781380

13791381
blocks, mask = blk._unstack(
1380-
unstacker, fill_value, new_placement=new_placement
1382+
unstacker,
1383+
fill_value,
1384+
new_placement=new_placement,
1385+
allow_fill=allow_fill,
13811386
)
13821387

13831388
new_blocks.extend(blocks)

0 commit comments

Comments
 (0)