From e415cf0cfa7e35f072463c710344d4aa63f5e7b7 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sat, 29 Feb 2020 13:21:51 -0800 Subject: [PATCH 1/4] ENH: infer freq in timedelta_range --- pandas/_testing.py | 4 ++-- pandas/core/arrays/timedeltas.py | 8 ++++++-- pandas/tests/indexes/timedeltas/test_timedelta_range.py | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/pandas/_testing.py b/pandas/_testing.py index a70f75d6cfaf4..4a5502982b795 100644 --- a/pandas/_testing.py +++ b/pandas/_testing.py @@ -742,9 +742,9 @@ def repr_class(x): raise_assert_detail(obj, msg, repr_class(left), repr_class(right)) -def assert_attr_equal(attr, left, right, obj="Attributes"): +def assert_attr_equal(attr: str, left, right, obj: str = "Attributes"): """ - checks attributes are equal. Both objects must have attribute. + Check attributes are equal. Both objects must have attribute. Parameters ---------- diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index 81fc934748d3e..8b51bd73a5d14 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -39,6 +39,7 @@ from pandas.core.algorithms import checked_add_with_arr from pandas.core.arrays import datetimelike as dtl import pandas.core.common as com +from pandas.core.construction import extract_array from pandas.tseries.frequencies import to_offset from pandas.tseries.offsets import Tick @@ -141,8 +142,7 @@ def dtype(self): # Constructors def __init__(self, values, dtype=_TD_DTYPE, freq=None, copy=False): - if isinstance(values, (ABCSeries, ABCIndexClass)): - values = values._values + values = extract_array(values) inferred_freq = getattr(values, "_freq", None) @@ -258,6 +258,10 @@ def _generate_range(cls, start, end, periods, freq, closed=None): index = _generate_regular_range(start, end, periods, freq) else: index = np.linspace(start.value, end.value, periods).astype("i8") + if len(index) >= 2: + # Infer a frequency + td = Timedelta(index[1] - index[0]) + freq = to_offset(td) if not left_closed: index = index[1:] diff --git a/pandas/tests/indexes/timedeltas/test_timedelta_range.py b/pandas/tests/indexes/timedeltas/test_timedelta_range.py index 9f12af9a96104..c07a6471c732f 100644 --- a/pandas/tests/indexes/timedeltas/test_timedelta_range.py +++ b/pandas/tests/indexes/timedeltas/test_timedelta_range.py @@ -38,6 +38,7 @@ def test_linspace_behavior(self, periods, freq): result = timedelta_range(start="0 days", end="4 days", periods=periods) expected = timedelta_range(start="0 days", end="4 days", freq=freq) tm.assert_index_equal(result, expected) + assert result.freq == freq def test_errors(self): # not enough params From af4a30791c1bc1607e301026215172a6094de9ef Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sat, 29 Feb 2020 13:22:39 -0800 Subject: [PATCH 2/4] whatsnew --- doc/source/whatsnew/v1.1.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index 0f18a1fd81815..164f1d20186bc 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -66,6 +66,7 @@ Other enhancements - :class:`Styler` may now render CSS more efficiently where multiple cells have the same styling (:issue:`30876`) - When writing directly to a sqlite connection :func:`to_sql` now supports the ``multi`` method (:issue:`29921`) - `OptionError` is now exposed in `pandas.errors` (:issue:`27553`) +- :func:`timedelta_range` will now infer a frequency when passed ``start``, ``stop``, and ``periods`` (:issue:`?????`) - .. --------------------------------------------------------------------------- From 8a7aa249d06704a4628337f1cd99af2abe7f7dd0 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sat, 29 Feb 2020 13:24:25 -0800 Subject: [PATCH 3/4] update GH ref --- doc/source/whatsnew/v1.1.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index 164f1d20186bc..999dee83cf7e0 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -66,7 +66,7 @@ Other enhancements - :class:`Styler` may now render CSS more efficiently where multiple cells have the same styling (:issue:`30876`) - When writing directly to a sqlite connection :func:`to_sql` now supports the ``multi`` method (:issue:`29921`) - `OptionError` is now exposed in `pandas.errors` (:issue:`27553`) -- :func:`timedelta_range` will now infer a frequency when passed ``start``, ``stop``, and ``periods`` (:issue:`?????`) +- :func:`timedelta_range` will now infer a frequency when passed ``start``, ``stop``, and ``periods`` (:issue:`32377`) - .. --------------------------------------------------------------------------- From 7e9f2e627d12801c63fabf08e41f3856c4416712 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sat, 29 Feb 2020 15:17:06 -0800 Subject: [PATCH 4/4] round freq --- pandas/core/arrays/timedeltas.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index 8b51bd73a5d14..749489a0a04fb 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -618,6 +618,10 @@ def __floordiv__(self, other): if self.freq is not None: # Note: freq gets division, not floor-division freq = self.freq / other + if freq.nanos == 0 and self.freq.nanos != 0: + # e.g. if self.freq is Nano(1) then dividing by 2 + # rounds down to zero + freq = None return type(self)(result.view("m8[ns]"), freq=freq) if not hasattr(other, "dtype"):