35
35
factorize ,
36
36
unique ,
37
37
)
38
+ from pandas .core .arrays ._mixins import NDArrayBackedExtensionArray
38
39
from pandas .core .arrays .categorical import factorize_from_iterable
39
40
from pandas .core .construction import ensure_wrapped_if_datetimelike
40
41
from pandas .core .frame import DataFrame
@@ -231,20 +232,31 @@ def arange_result(self) -> tuple[npt.NDArray[np.intp], npt.NDArray[np.bool_]]:
231
232
return new_values , mask .any (0 )
232
233
# TODO: in all tests we have mask.any(0).all(); can we rely on that?
233
234
234
- def get_result (self , values , value_columns , fill_value ) -> DataFrame :
235
+ def get_result (self , obj , value_columns , fill_value ) -> DataFrame :
236
+ values = obj ._values
235
237
if values .ndim == 1 :
236
238
values = values [:, np .newaxis ]
237
239
238
240
if value_columns is None and values .shape [1 ] != 1 : # pragma: no cover
239
241
raise ValueError ("must pass column labels for multi-column data" )
240
242
241
- values , _ = self .get_new_values (values , fill_value )
243
+ new_values , _ = self .get_new_values (values , fill_value )
242
244
columns = self .get_new_columns (value_columns )
243
245
index = self .new_index
244
246
245
- return self .constructor (
246
- values , index = index , columns = columns , dtype = values .dtype
247
+ result = self .constructor (
248
+ new_values , index = index , columns = columns , dtype = new_values .dtype , copy = False
247
249
)
250
+ if isinstance (values , np .ndarray ):
251
+ base , new_base = values .base , new_values .base
252
+ elif isinstance (values , NDArrayBackedExtensionArray ):
253
+ base , new_base = values ._ndarray .base , new_values ._ndarray .base
254
+ else :
255
+ base , new_base = 1 , 2 # type: ignore[assignment]
256
+ if base is new_base :
257
+ # We can only get here if one of the dimensions is size 1
258
+ result ._mgr .add_references (obj ._mgr )
259
+ return result
248
260
249
261
def get_new_values (self , values , fill_value = None ):
250
262
if values .ndim == 1 :
@@ -532,9 +544,7 @@ def unstack(
532
544
unstacker = _Unstacker (
533
545
obj .index , level = level , constructor = obj ._constructor_expanddim , sort = sort
534
546
)
535
- return unstacker .get_result (
536
- obj ._values , value_columns = None , fill_value = fill_value
537
- )
547
+ return unstacker .get_result (obj , value_columns = None , fill_value = fill_value )
538
548
539
549
540
550
def _unstack_frame (
@@ -550,7 +560,7 @@ def _unstack_frame(
550
560
return obj ._constructor_from_mgr (mgr , axes = mgr .axes )
551
561
else :
552
562
return unstacker .get_result (
553
- obj . _values , value_columns = obj .columns , fill_value = fill_value
563
+ obj , value_columns = obj .columns , fill_value = fill_value
554
564
)
555
565
556
566
0 commit comments