Skip to content

Commit d219c2c

Browse files
authored
ENH: infer freq in timedelta_range (#32377)
1 parent 08deb10 commit d219c2c

File tree

4 files changed

+14
-4
lines changed

4 files changed

+14
-4
lines changed

doc/source/whatsnew/v1.1.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Other enhancements
6666
- :class:`Styler` may now render CSS more efficiently where multiple cells have the same styling (:issue:`30876`)
6767
- When writing directly to a sqlite connection :func:`to_sql` now supports the ``multi`` method (:issue:`29921`)
6868
- `OptionError` is now exposed in `pandas.errors` (:issue:`27553`)
69+
- :func:`timedelta_range` will now infer a frequency when passed ``start``, ``stop``, and ``periods`` (:issue:`32377`)
6970
-
7071

7172
.. ---------------------------------------------------------------------------

pandas/_testing.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -742,9 +742,9 @@ def repr_class(x):
742742
raise_assert_detail(obj, msg, repr_class(left), repr_class(right))
743743

744744

745-
def assert_attr_equal(attr, left, right, obj="Attributes"):
745+
def assert_attr_equal(attr: str, left, right, obj: str = "Attributes"):
746746
"""
747-
checks attributes are equal. Both objects must have attribute.
747+
Check attributes are equal. Both objects must have attribute.
748748
749749
Parameters
750750
----------

pandas/core/arrays/timedeltas.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
from pandas.core.algorithms import checked_add_with_arr
4040
from pandas.core.arrays import datetimelike as dtl
4141
import pandas.core.common as com
42+
from pandas.core.construction import extract_array
4243

4344
from pandas.tseries.frequencies import to_offset
4445
from pandas.tseries.offsets import Tick
@@ -141,8 +142,7 @@ def dtype(self):
141142
# Constructors
142143

143144
def __init__(self, values, dtype=_TD_DTYPE, freq=None, copy=False):
144-
if isinstance(values, (ABCSeries, ABCIndexClass)):
145-
values = values._values
145+
values = extract_array(values)
146146

147147
inferred_freq = getattr(values, "_freq", None)
148148

@@ -258,6 +258,10 @@ def _generate_range(cls, start, end, periods, freq, closed=None):
258258
index = _generate_regular_range(start, end, periods, freq)
259259
else:
260260
index = np.linspace(start.value, end.value, periods).astype("i8")
261+
if len(index) >= 2:
262+
# Infer a frequency
263+
td = Timedelta(index[1] - index[0])
264+
freq = to_offset(td)
261265

262266
if not left_closed:
263267
index = index[1:]
@@ -614,6 +618,10 @@ def __floordiv__(self, other):
614618
if self.freq is not None:
615619
# Note: freq gets division, not floor-division
616620
freq = self.freq / other
621+
if freq.nanos == 0 and self.freq.nanos != 0:
622+
# e.g. if self.freq is Nano(1) then dividing by 2
623+
# rounds down to zero
624+
freq = None
617625
return type(self)(result.view("m8[ns]"), freq=freq)
618626

619627
if not hasattr(other, "dtype"):

pandas/tests/indexes/timedeltas/test_timedelta_range.py

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def test_linspace_behavior(self, periods, freq):
3838
result = timedelta_range(start="0 days", end="4 days", periods=periods)
3939
expected = timedelta_range(start="0 days", end="4 days", freq=freq)
4040
tm.assert_index_equal(result, expected)
41+
assert result.freq == freq
4142

4243
def test_errors(self):
4344
# not enough params

0 commit comments

Comments
 (0)