Skip to content

Commit 774a130

Browse files
committed
BUG: Series/DF constructors may drop Timedelta/Timestamp nanoseconds
use cast_scalar_to_array as base for ndarray creation
1 parent 0e87f77 commit 774a130

File tree

1 file changed

+20
-24
lines changed

1 file changed

+20
-24
lines changed

pandas/core/dtypes/cast.py

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,12 +1654,28 @@ def cast_scalar_to_array(
16541654
16551655
"""
16561656
if dtype is None:
1657-
dtype, fill_value = infer_dtype_from_scalar(value)
1657+
dtype, value = infer_dtype_from_scalar(value)
16581658
else:
1659-
fill_value = value
1659+
if shape and is_integer_dtype(dtype) and isna(value):
1660+
# coerce if we have nan for an integer dtype
1661+
dtype = np.dtype("float64")
1662+
elif isinstance(dtype, np.dtype) and dtype.kind in ("U", "S"):
1663+
# we need to coerce to object dtype to avoid
1664+
# to allow numpy to take our string as a scalar value
1665+
dtype = np.dtype("object")
1666+
if not isna(value):
1667+
value = ensure_str(value)
1668+
elif dtype.kind in ["M", "m"]:
1669+
# GH38032: filling in Timedelta/Timestamp drops nanoseconds
1670+
if isinstance(value, (Timedelta, Timestamp)):
1671+
value = value.to_numpy()
1672+
# GH36541: filling datetime-like array directly with pd.NaT
1673+
# raises ValueError: cannot convert float NaN to integer
1674+
elif is_valid_nat_for_dtype(value, dtype):
1675+
value = np.datetime64("NaT")
16601676

16611677
values = np.empty(shape, dtype=dtype)
1662-
values.fill(fill_value)
1678+
values.fill(value)
16631679

16641680
return values
16651681

@@ -1687,27 +1703,7 @@ def construct_1d_arraylike_from_scalar(
16871703
subarr = cls._from_sequence([value] * length, dtype=dtype)
16881704

16891705
else:
1690-
1691-
if length and is_integer_dtype(dtype) and isna(value):
1692-
# coerce if we have nan for an integer dtype
1693-
dtype = np.dtype("float64")
1694-
elif isinstance(dtype, np.dtype) and dtype.kind in ("U", "S"):
1695-
# we need to coerce to object dtype to avoid
1696-
# to allow numpy to take our string as a scalar value
1697-
dtype = np.dtype("object")
1698-
if not isna(value):
1699-
value = ensure_str(value)
1700-
elif dtype.kind in ["M", "m"]:
1701-
# GH38032: filling in Timedelta/Timestamp drops nanoseconds
1702-
if isinstance(value, (Timedelta, Timestamp)):
1703-
value = value.to_numpy()
1704-
# GH36541: filling datetime-like array directly with pd.NaT
1705-
# raises ValueError: cannot convert float NaN to integer
1706-
elif is_valid_nat_for_dtype(value, dtype):
1707-
value = np.datetime64("NaT")
1708-
1709-
subarr = np.empty(length, dtype=dtype)
1710-
subarr.fill(value)
1706+
subarr = cast_scalar_to_array(length, value, dtype)
17111707

17121708
return subarr
17131709

0 commit comments

Comments
 (0)