Skip to content

Commit 8374c65

Browse files
authored
BUG: Series[object].unstack preserve object dtype (#44595)
1 parent 53eeaff commit 8374c65

File tree

4 files changed

+21
-18
lines changed

4 files changed

+21
-18
lines changed

doc/source/whatsnew/v1.4.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,7 @@ Reshaping
704704
- Bug in :meth:`DataFrame.append` failing to retain ``index.name`` when appending a list of :class:`Series` objects (:issue:`44109`)
705705
- Fixed metadata propagation in :meth:`Dataframe.apply` method, consequently fixing the same issue for :meth:`Dataframe.transform`, :meth:`Dataframe.nunique` and :meth:`Dataframe.mode` (:issue:`28283`)
706706
- Bug in :meth:`DataFrame.stack` with ``ExtensionDtype`` columns incorrectly raising (:issue:`43561`)
707+
- Bug in :meth:`Series.unstack` with object doing unwanted type inference on resulting columns (:issue:`44595`)
707708
-
708709

709710
Sparse

pandas/core/reshape/reshape.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,9 @@ def get_result(self, values, value_columns, fill_value):
213213
columns = self.get_new_columns(value_columns)
214214
index = self.new_index
215215

216-
return self.constructor(values, index=index, columns=columns)
216+
return self.constructor(
217+
values, index=index, columns=columns, dtype=values.dtype
218+
)
217219

218220
def get_new_values(self, values, fill_value=None):
219221

pandas/tests/extension/base/reshaping.py

+5-17
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,6 @@
33
import numpy as np
44
import pytest
55

6-
from pandas.core.dtypes.common import (
7-
is_datetime64tz_dtype,
8-
is_interval_dtype,
9-
is_period_dtype,
10-
)
11-
126
import pandas as pd
137
from pandas.api.extensions import ExtensionArray
148
from pandas.core.internals import ExtensionBlock
@@ -327,17 +321,11 @@ def test_unstack(self, data, index, obj):
327321
expected = ser.astype(object).unstack(
328322
level=level, fill_value=data.dtype.na_value
329323
)
330-
if obj == "series":
331-
# TODO: special cases belong in dtype-specific tests
332-
if is_datetime64tz_dtype(data.dtype):
333-
assert expected.dtypes.apply(is_datetime64tz_dtype).all()
334-
expected = expected.astype(object)
335-
if is_period_dtype(data.dtype):
336-
assert expected.dtypes.apply(is_period_dtype).all()
337-
expected = expected.astype(object)
338-
if is_interval_dtype(data.dtype):
339-
assert expected.dtypes.apply(is_interval_dtype).all()
340-
expected = expected.astype(object)
324+
if obj == "series" and not isinstance(ser.dtype, pd.SparseDtype):
325+
# GH#34457 SparseArray.astype(object) gives Sparse[object]
326+
# instead of np.dtype(object)
327+
assert (expected.dtypes == object).all()
328+
341329
result = result.astype(object)
342330

343331
self.assert_frame_equal(result, expected)

pandas/tests/series/methods/test_unstack.py

+12
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@
1010
import pandas._testing as tm
1111

1212

13+
def test_unstack_preserves_object():
14+
mi = MultiIndex.from_product([["bar", "foo"], ["one", "two"]])
15+
16+
ser = Series(np.arange(4.0), index=mi, dtype=object)
17+
18+
res1 = ser.unstack()
19+
assert (res1.dtypes == object).all()
20+
21+
res2 = ser.unstack(level=0)
22+
assert (res2.dtypes == object).all()
23+
24+
1325
def test_unstack():
1426
index = MultiIndex(
1527
levels=[["bar", "foo"], ["one", "three", "two"]],

0 commit comments

Comments
 (0)