Skip to content

Commit 83ce781

Browse files
justinessertKevin D Smith
authored and
Kevin D Smith
committed
BUG: instantiation using a dict with a period scalar (pandas-dev#35966)
1 parent dbd2ba0 commit 83ce781

File tree

7 files changed

+51
-7
lines changed

7 files changed

+51
-7
lines changed

doc/source/whatsnew/v1.2.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ Sparse
334334
ExtensionArray
335335
^^^^^^^^^^^^^^
336336

337-
-
337+
- 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`)
338338
-
339339

340340

pandas/core/construction.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ def sanitize_array(
472472

473473
# figure out the dtype from the value (upcast if necessary)
474474
if dtype is None:
475-
dtype, value = infer_dtype_from_scalar(value)
475+
dtype, value = infer_dtype_from_scalar(value, pandas_dtype=True)
476476
else:
477477
# need to possibly convert the value here
478478
value = maybe_cast_to_datetime(value, dtype)

pandas/core/dtypes/cast.py

-1
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,6 @@ def infer_dtype_from_scalar(val, pandas_dtype: bool = False) -> Tuple[DtypeObj,
709709
elif pandas_dtype:
710710
if lib.is_period(val):
711711
dtype = PeriodDtype(freq=val.freq)
712-
val = val.ordinal
713712
elif lib.is_interval(val):
714713
subtype = infer_dtype_from_scalar(val.left, pandas_dtype=True)[0]
715714
dtype = IntervalDtype(subtype=subtype)

pandas/core/indexes/interval.py

+2
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,8 @@ def _maybe_convert_i8(self, key):
589589
if scalar:
590590
# Timestamp/Timedelta
591591
key_dtype, key_i8 = infer_dtype_from_scalar(key, pandas_dtype=True)
592+
if lib.is_period(key):
593+
key_i8 = key.ordinal
592594
else:
593595
# DatetimeIndex/TimedeltaIndex
594596
key_dtype, key_i8 = key.dtype, Index(key.asi8)

pandas/tests/dtypes/cast/test_infer_dtype.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,11 @@ def test_infer_dtype_from_period(freq, pandas_dtype):
8484

8585
if pandas_dtype:
8686
exp_dtype = f"period[{freq}]"
87-
exp_val = p.ordinal
8887
else:
8988
exp_dtype = np.object_
90-
exp_val = p
9189

9290
assert dtype == exp_dtype
93-
assert val == exp_val
91+
assert val == p
9492

9593

9694
@pytest.mark.parametrize(

pandas/tests/frame/test_constructors.py

+18
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,24 @@ def test_constructor_period_dict(self):
717717
assert df["a"].dtype == a.dtype
718718
assert df["b"].dtype == b.dtype
719719

720+
@pytest.mark.parametrize(
721+
"data,dtype",
722+
[
723+
(pd.Period("2012-01", freq="M"), "period[M]"),
724+
(pd.Period("2012-02-01", freq="D"), "period[D]"),
725+
(Interval(left=0, right=5), IntervalDtype("int64")),
726+
(Interval(left=0.1, right=0.5), IntervalDtype("float64")),
727+
],
728+
)
729+
def test_constructor_period_dict_scalar(self, data, dtype):
730+
# scalar periods
731+
df = DataFrame({"a": data}, index=[0])
732+
assert df["a"].dtype == dtype
733+
734+
expected = DataFrame(index=[0], columns=["a"], data=data)
735+
736+
tm.assert_frame_equal(df, expected)
737+
720738
@pytest.mark.parametrize(
721739
"data,dtype",
722740
[

pandas/tests/series/test_constructors.py

+28-1
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,23 @@
88
from pandas._libs import iNaT, lib
99

1010
from pandas.core.dtypes.common import is_categorical_dtype, is_datetime64tz_dtype
11-
from pandas.core.dtypes.dtypes import CategoricalDtype
11+
from pandas.core.dtypes.dtypes import (
12+
CategoricalDtype,
13+
DatetimeTZDtype,
14+
IntervalDtype,
15+
PeriodDtype,
16+
)
1217

1318
import pandas as pd
1419
from pandas import (
1520
Categorical,
1621
DataFrame,
1722
Index,
23+
Interval,
1824
IntervalIndex,
1925
MultiIndex,
2026
NaT,
27+
Period,
2128
Series,
2229
Timestamp,
2330
date_range,
@@ -1075,6 +1082,26 @@ def test_constructor_dict_order(self):
10751082
expected = Series([1, 0, 2], index=list("bac"))
10761083
tm.assert_series_equal(result, expected)
10771084

1085+
@pytest.mark.parametrize(
1086+
"data,dtype",
1087+
[
1088+
(Period("2020-01"), PeriodDtype("M")),
1089+
(Interval(left=0, right=5), IntervalDtype("int64")),
1090+
(
1091+
Timestamp("2011-01-01", tz="US/Eastern"),
1092+
DatetimeTZDtype(tz="US/Eastern"),
1093+
),
1094+
],
1095+
)
1096+
def test_constructor_dict_extension(self, data, dtype):
1097+
d = {"a": data}
1098+
result = Series(d, index=["a"])
1099+
expected = Series(data, index=["a"], dtype=dtype)
1100+
1101+
assert result.dtype == dtype
1102+
1103+
tm.assert_series_equal(result, expected)
1104+
10781105
@pytest.mark.parametrize("value", [2, np.nan, None, float("nan")])
10791106
def test_constructor_dict_nan_key(self, value):
10801107
# GH 18480

0 commit comments

Comments
 (0)