Skip to content

BUG: instantiation using a dict with a period scalar #35966

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Sep 11, 2020
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v1.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ Sparse
ExtensionArray
^^^^^^^^^^^^^^

-
- Fixed Bug where :class:`DataFrame` column set to scalar extension type via a dict instantion was considered an object type rather than the extension type (:issue:`35965`)
-


Expand Down
2 changes: 1 addition & 1 deletion pandas/core/construction.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ def sanitize_array(

# figure out the dtype from the value (upcast if necessary)
if dtype is None:
dtype, value = infer_dtype_from_scalar(value)
dtype, value = infer_dtype_from_scalar(value, pandas_dtype=True)
else:
# need to possibly convert the value here
value = maybe_cast_to_datetime(value, dtype)
Expand Down
1 change: 0 additions & 1 deletion pandas/core/dtypes/cast.py
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,6 @@ def infer_dtype_from_scalar(val, pandas_dtype: bool = False) -> Tuple[DtypeObj,
elif pandas_dtype:
if lib.is_period(val):
dtype = PeriodDtype(freq=val.freq)
val = val.ordinal
elif lib.is_interval(val):
subtype = infer_dtype_from_scalar(val.left, pandas_dtype=True)[0]
dtype = IntervalDtype(subtype=subtype)
Expand Down
2 changes: 2 additions & 0 deletions pandas/core/indexes/interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,8 @@ def _maybe_convert_i8(self, key):
if scalar:
# Timestamp/Timedelta
key_dtype, key_i8 = infer_dtype_from_scalar(key, pandas_dtype=True)
if lib.is_period(key):
key_i8 = key.ordinal
else:
# DatetimeIndex/TimedeltaIndex
key_dtype, key_i8 = key.dtype, Index(key.asi8)
Expand Down
4 changes: 1 addition & 3 deletions pandas/tests/dtypes/cast/test_infer_dtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,11 @@ def test_infer_dtype_from_period(freq, pandas_dtype):

if pandas_dtype:
exp_dtype = f"period[{freq}]"
exp_val = p.ordinal
else:
exp_dtype = np.object_
exp_val = p

assert dtype == exp_dtype
assert val == exp_val
assert val == p


@pytest.mark.parametrize(
Expand Down
18 changes: 18 additions & 0 deletions pandas/tests/frame/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,24 @@ def test_constructor_period_dict(self):
assert df["a"].dtype == a.dtype
assert df["b"].dtype == b.dtype

@pytest.mark.parametrize(
"data,dtype",
[
(pd.Period("2012-01", freq="M"), "period[M]"),
(pd.Period("2012-02-01", freq="D"), "period[D]"),
(Interval(left=0, right=5), IntervalDtype("int64")),
(Interval(left=0.1, right=0.5), IntervalDtype("float64")),
],
)
def test_constructor_period_dict_scalar(self, data, dtype):
# scalar periods
df = DataFrame({"a": data}, index=[0])
assert df["a"].dtype == dtype

expected = DataFrame(index=[0], columns=["a"], data=data)

tm.assert_frame_equal(df, expected)

@pytest.mark.parametrize(
"data,dtype",
[
Expand Down