123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- from datetime import timedelta
- import numpy as np
- import pytest
- import pandas as pd
- from pandas import (
- Index,
- NaT,
- Series,
- Timedelta,
- TimedeltaIndex,
- timedelta_range,
- )
- import pandas._testing as tm
- from pandas.core.arrays import TimedeltaArray
- from pandas.tests.indexes.datetimelike import DatetimeLike
- randn = np.random.randn
- class TestTimedeltaIndex(DatetimeLike):
- _index_cls = TimedeltaIndex
- @pytest.fixture
- def simple_index(self) -> TimedeltaIndex:
- index = pd.to_timedelta(range(5), unit="d")._with_freq("infer")
- assert index.freq == "D"
- ret = index + pd.offsets.Hour(1)
- assert ret.freq == "D"
- return ret
- @pytest.fixture
- def index(self):
- return tm.makeTimedeltaIndex(10)
- def test_numeric_compat(self):
- # Dummy method to override super's version; this test is now done
- # in test_arithmetic.py
- pass
- def test_shift(self):
- pass # this is handled in test_arithmetic.py
- def test_misc_coverage(self):
- rng = timedelta_range("1 day", periods=5)
- result = rng.groupby(rng.days)
- assert isinstance(list(result.values())[0][0], Timedelta)
- def test_map(self):
- # test_map_dictlike generally tests
- rng = timedelta_range("1 day", periods=10)
- f = lambda x: x.days
- result = rng.map(f)
- exp = Index([f(x) for x in rng], dtype=np.int64)
- tm.assert_index_equal(result, exp)
- def test_pass_TimedeltaIndex_to_index(self):
- rng = timedelta_range("1 days", "10 days")
- idx = Index(rng, dtype=object)
- expected = Index(rng.to_pytimedelta(), dtype=object)
- tm.assert_numpy_array_equal(idx.values, expected.values)
- def test_fields(self):
- rng = timedelta_range("1 days, 10:11:12.100123456", periods=2, freq="s")
- tm.assert_index_equal(rng.days, Index([1, 1], dtype=np.int64))
- tm.assert_index_equal(
- rng.seconds,
- Index([10 * 3600 + 11 * 60 + 12, 10 * 3600 + 11 * 60 + 13], dtype=np.int32),
- )
- tm.assert_index_equal(
- rng.microseconds,
- Index([100 * 1000 + 123, 100 * 1000 + 123], dtype=np.int32),
- )
- tm.assert_index_equal(rng.nanoseconds, Index([456, 456], dtype=np.int32))
- msg = "'TimedeltaIndex' object has no attribute '{}'"
- with pytest.raises(AttributeError, match=msg.format("hours")):
- rng.hours
- with pytest.raises(AttributeError, match=msg.format("minutes")):
- rng.minutes
- with pytest.raises(AttributeError, match=msg.format("milliseconds")):
- rng.milliseconds
- # with nat
- s = Series(rng)
- s[1] = np.nan
- tm.assert_series_equal(s.dt.days, Series([1, np.nan], index=[0, 1]))
- tm.assert_series_equal(
- s.dt.seconds, Series([10 * 3600 + 11 * 60 + 12, np.nan], index=[0, 1])
- )
- # preserve name (GH15589)
- rng.name = "name"
- assert rng.days.name == "name"
- def test_freq_conversion_always_floating(self):
- # pre-2.0 td64 astype converted to float64. now for supported units
- # (s, ms, us, ns) this converts to the requested dtype.
- # This matches TDA and Series
- tdi = timedelta_range("1 Day", periods=30)
- res = tdi.astype("m8[s]")
- exp_values = np.asarray(tdi).astype("m8[s]")
- exp_tda = TimedeltaArray._simple_new(
- exp_values, dtype=exp_values.dtype, freq=tdi.freq
- )
- expected = Index(exp_tda)
- assert expected.dtype == "m8[s]"
- tm.assert_index_equal(res, expected)
- # check this matches Series and TimedeltaArray
- res = tdi._data.astype("m8[s]")
- tm.assert_equal(res, expected._values)
- res = tdi.to_series().astype("m8[s]")
- tm.assert_equal(res._values, expected._values._with_freq(None))
- def test_freq_conversion(self, index_or_series):
- # doc example
- scalar = Timedelta(days=31)
- td = index_or_series(
- [scalar, scalar, scalar + timedelta(minutes=5, seconds=3), NaT],
- dtype="m8[ns]",
- )
- result = td / np.timedelta64(1, "D")
- expected = index_or_series(
- [31, 31, (31 * 86400 + 5 * 60 + 3) / 86400.0, np.nan]
- )
- tm.assert_equal(result, expected)
- # We don't support "D" reso, so we use the pre-2.0 behavior
- # casting to float64
- msg = (
- r"Cannot convert from timedelta64\[ns\] to timedelta64\[D\]. "
- "Supported resolutions are 's', 'ms', 'us', 'ns'"
- )
- with pytest.raises(ValueError, match=msg):
- td.astype("timedelta64[D]")
- result = td / np.timedelta64(1, "s")
- expected = index_or_series(
- [31 * 86400, 31 * 86400, 31 * 86400 + 5 * 60 + 3, np.nan]
- )
- tm.assert_equal(result, expected)
- exp_values = np.asarray(td).astype("m8[s]")
- exp_tda = TimedeltaArray._simple_new(exp_values, dtype=exp_values.dtype)
- expected = index_or_series(exp_tda)
- assert expected.dtype == "m8[s]"
- result = td.astype("timedelta64[s]")
- tm.assert_equal(result, expected)
|