Skip to content

Commit 546591f

Browse files
API: integer values and non-nano dtype (#51092)
* API: integer values and non-nano dtype * troubleshoot circleci * Update doc/source/whatsnew/v2.0.0.rst --------- Co-authored-by: Matthew Roeschke <[email protected]>
1 parent edad036 commit 546591f

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

doc/source/whatsnew/v2.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,7 @@ Other API changes
706706
- Passing ``dtype`` of "timedelta64[s]", "timedelta64[ms]", or "timedelta64[us]" to :class:`TimedeltaIndex`, :class:`Series`, or :class:`DataFrame` constructors will now retain that dtype instead of casting to "timedelta64[ns]"; passing a dtype with lower resolution for :class:`Series` or :class:`DataFrame` will be cast to the lowest supported resolution "timedelta64[s]" (:issue:`49014`)
707707
- Passing a ``np.datetime64`` object with non-nanosecond resolution to :class:`Timestamp` will retain the input resolution if it is "s", "ms", "us", or "ns"; otherwise it will be cast to the closest supported resolution (:issue:`49008`)
708708
- Passing ``datetime64`` values with resolution other than nanosecond to :func:`to_datetime` will retain the input resolution if it is "s", "ms", "us", or "ns"; otherwise it will be cast to the closest supported resolution (:issue:`50369`)
709+
- Passing integer values and a non-nanosecond datetime64 dtype (e.g. "datetime64[s]") :class:`DataFrame`, :class:`Series`, or :class:`Index` will treat the values as multiples of the dtype's unit, matching the behavior of e.g. ``Series(np.array(values, dtype="M8[s]"))`` (:issue:`51092`)
709710
- Passing a string in ISO-8601 format to :class:`Timestamp` will retain the resolution of the parsed input if it is "s", "ms", "us", or "ns"; otherwise it will be cast to the closest supported resolution (:issue:`49737`)
710711
- The ``other`` argument in :meth:`DataFrame.mask` and :meth:`Series.mask` now defaults to ``no_default`` instead of ``np.nan`` consistent with :meth:`DataFrame.where` and :meth:`Series.where`. Entries will be filled with the corresponding NULL value (``np.nan`` for numpy dtypes, ``pd.NA`` for extension dtypes). (:issue:`49111`)
711712
- Changed behavior of :meth:`Series.quantile` and :meth:`DataFrame.quantile` with :class:`SparseDtype` to retain sparse dtype (:issue:`49583`)

pandas/core/arrays/datetimes.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ def _from_sequence_not_strict(
335335
dayfirst=dayfirst,
336336
yearfirst=yearfirst,
337337
ambiguous=ambiguous,
338+
out_unit=unit,
338339
)
339340
# We have to call this again after possibly inferring a tz above
340341
_validate_tz_from_dtype(dtype, tz, explicit_tz_none)
@@ -1966,6 +1967,7 @@ def _sequence_to_dt64ns(
19661967
dayfirst: bool = False,
19671968
yearfirst: bool = False,
19681969
ambiguous: TimeAmbiguous = "raise",
1970+
out_unit: str | None = None,
19691971
):
19701972
"""
19711973
Parameters
@@ -1977,6 +1979,8 @@ def _sequence_to_dt64ns(
19771979
yearfirst : bool, default False
19781980
ambiguous : str, bool, or arraylike, default 'raise'
19791981
See pandas._libs.tslibs.tzconversion.tz_localize_to_utc.
1982+
out_unit : str or None, default None
1983+
Desired output resolution.
19801984
19811985
Returns
19821986
-------
@@ -2004,6 +2008,10 @@ def _sequence_to_dt64ns(
20042008
data, copy = maybe_convert_dtype(data, copy, tz=tz)
20052009
data_dtype = getattr(data, "dtype", None)
20062010

2011+
out_dtype = DT64NS_DTYPE
2012+
if out_unit is not None:
2013+
out_dtype = np.dtype(f"M8[{out_unit}]")
2014+
20072015
if (
20082016
is_object_dtype(data_dtype)
20092017
or is_string_dtype(data_dtype)
@@ -2090,7 +2098,7 @@ def _sequence_to_dt64ns(
20902098
# assume this data are epoch timestamps
20912099
if data.dtype != INT64_DTYPE:
20922100
data = data.astype(np.int64, copy=False)
2093-
result = data.view(DT64NS_DTYPE)
2101+
result = data.view(out_dtype)
20942102

20952103
if copy:
20962104
result = result.copy()
@@ -2203,7 +2211,7 @@ def maybe_convert_dtype(data, copy: bool, tz: tzinfo | None = None):
22032211
# GH#23675, GH#45573 deprecated to treat symmetrically with integer dtypes.
22042212
# Note: data.astype(np.int64) fails ARM tests, see
22052213
# https://github.com/pandas-dev/pandas/issues/49468.
2206-
data = data.astype("M8[ns]").view("i8")
2214+
data = data.astype(DT64NS_DTYPE).view("i8")
22072215
copy = False
22082216

22092217
elif is_timedelta64_dtype(data.dtype) or is_bool_dtype(data.dtype):

pandas/tests/series/test_constructors.py

+10
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@
5252

5353

5454
class TestSeriesConstructors:
55+
def test_from_ints_with_non_nano_dt64_dtype(self, index_or_series):
56+
values = np.arange(10)
57+
58+
res = index_or_series(values, dtype="M8[s]")
59+
expected = index_or_series(values.astype("M8[s]"))
60+
tm.assert_equal(res, expected)
61+
62+
res = index_or_series(list(values), dtype="M8[s]")
63+
tm.assert_equal(res, expected)
64+
5565
def test_from_na_value_and_interval_of_datetime_dtype(self):
5666
# GH#41805
5767
ser = Series([None], dtype="interval[datetime64[ns]]")

0 commit comments

Comments
 (0)