done
This commit is contained in:
		| @ -0,0 +1,181 @@ | ||||
| from datetime import timedelta | ||||
|  | ||||
| import numpy as np | ||||
| import pytest | ||||
|  | ||||
| import pandas as pd | ||||
| from pandas import ( | ||||
|     Index, | ||||
|     NaT, | ||||
|     Timedelta, | ||||
|     TimedeltaIndex, | ||||
|     timedelta_range, | ||||
| ) | ||||
| import pandas._testing as tm | ||||
| from pandas.core.arrays import TimedeltaArray | ||||
|  | ||||
|  | ||||
| class TestTimedeltaIndex: | ||||
|     def test_astype_object(self): | ||||
|         idx = timedelta_range(start="1 days", periods=4, freq="D", name="idx") | ||||
|         expected_list = [ | ||||
|             Timedelta("1 days"), | ||||
|             Timedelta("2 days"), | ||||
|             Timedelta("3 days"), | ||||
|             Timedelta("4 days"), | ||||
|         ] | ||||
|         result = idx.astype(object) | ||||
|         expected = Index(expected_list, dtype=object, name="idx") | ||||
|         tm.assert_index_equal(result, expected) | ||||
|         assert idx.tolist() == expected_list | ||||
|  | ||||
|     def test_astype_object_with_nat(self): | ||||
|         idx = TimedeltaIndex( | ||||
|             [timedelta(days=1), timedelta(days=2), NaT, timedelta(days=4)], name="idx" | ||||
|         ) | ||||
|         expected_list = [ | ||||
|             Timedelta("1 days"), | ||||
|             Timedelta("2 days"), | ||||
|             NaT, | ||||
|             Timedelta("4 days"), | ||||
|         ] | ||||
|         result = idx.astype(object) | ||||
|         expected = Index(expected_list, dtype=object, name="idx") | ||||
|         tm.assert_index_equal(result, expected) | ||||
|         assert idx.tolist() == expected_list | ||||
|  | ||||
|     def test_astype(self, using_infer_string): | ||||
|         # GH 13149, GH 13209 | ||||
|         idx = TimedeltaIndex([1e14, "NaT", NaT, np.nan], name="idx") | ||||
|  | ||||
|         result = idx.astype(object) | ||||
|         expected = Index( | ||||
|             [Timedelta("1 days 03:46:40")] + [NaT] * 3, dtype=object, name="idx" | ||||
|         ) | ||||
|         tm.assert_index_equal(result, expected) | ||||
|  | ||||
|         result = idx.astype(np.int64) | ||||
|         expected = Index( | ||||
|             [100000000000000] + [-9223372036854775808] * 3, dtype=np.int64, name="idx" | ||||
|         ) | ||||
|         tm.assert_index_equal(result, expected) | ||||
|  | ||||
|         result = idx.astype(str) | ||||
|         if using_infer_string: | ||||
|             expected = Index( | ||||
|                 [str(x) if x is not NaT else None for x in idx], name="idx", dtype="str" | ||||
|             ) | ||||
|         else: | ||||
|             expected = Index([str(x) for x in idx], name="idx", dtype=object) | ||||
|         tm.assert_index_equal(result, expected) | ||||
|  | ||||
|         rng = timedelta_range("1 days", periods=10) | ||||
|         result = rng.astype("i8") | ||||
|         tm.assert_index_equal(result, Index(rng.asi8)) | ||||
|         tm.assert_numpy_array_equal(rng.asi8, result.values) | ||||
|  | ||||
|     def test_astype_uint(self): | ||||
|         arr = timedelta_range("1h", periods=2) | ||||
|  | ||||
|         with pytest.raises(TypeError, match=r"Do obj.astype\('int64'\)"): | ||||
|             arr.astype("uint64") | ||||
|         with pytest.raises(TypeError, match=r"Do obj.astype\('int64'\)"): | ||||
|             arr.astype("uint32") | ||||
|  | ||||
|     def test_astype_timedelta64(self): | ||||
|         # GH 13149, GH 13209 | ||||
|         idx = TimedeltaIndex([1e14, "NaT", NaT, np.nan]) | ||||
|  | ||||
|         msg = ( | ||||
|             r"Cannot convert from timedelta64\[ns\] to timedelta64. " | ||||
|             "Supported resolutions are 's', 'ms', 'us', 'ns'" | ||||
|         ) | ||||
|         with pytest.raises(ValueError, match=msg): | ||||
|             idx.astype("timedelta64") | ||||
|  | ||||
|         result = idx.astype("timedelta64[ns]") | ||||
|         tm.assert_index_equal(result, idx) | ||||
|         assert result is not idx | ||||
|  | ||||
|         result = idx.astype("timedelta64[ns]", copy=False) | ||||
|         tm.assert_index_equal(result, idx) | ||||
|         assert result is idx | ||||
|  | ||||
|     def test_astype_to_td64d_raises(self, index_or_series): | ||||
|         # We don't support "D" reso | ||||
|         scalar = Timedelta(days=31) | ||||
|         td = index_or_series( | ||||
|             [scalar, scalar, scalar + timedelta(minutes=5, seconds=3), NaT], | ||||
|             dtype="m8[ns]", | ||||
|         ) | ||||
|         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]") | ||||
|  | ||||
|     def test_astype_ms_to_s(self, index_or_series): | ||||
|         scalar = Timedelta(days=31) | ||||
|         td = index_or_series( | ||||
|             [scalar, scalar, scalar + timedelta(minutes=5, seconds=3), NaT], | ||||
|             dtype="m8[ns]", | ||||
|         ) | ||||
|  | ||||
|         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) | ||||
|  | ||||
|     def test_astype_freq_conversion(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)) | ||||
|  | ||||
|     @pytest.mark.parametrize("dtype", [float, "datetime64", "datetime64[ns]"]) | ||||
|     def test_astype_raises(self, dtype): | ||||
|         # GH 13149, GH 13209 | ||||
|         idx = TimedeltaIndex([1e14, "NaT", NaT, np.nan]) | ||||
|         msg = "Cannot cast TimedeltaIndex to dtype" | ||||
|         with pytest.raises(TypeError, match=msg): | ||||
|             idx.astype(dtype) | ||||
|  | ||||
|     def test_astype_category(self): | ||||
|         obj = timedelta_range("1h", periods=2, freq="h") | ||||
|  | ||||
|         result = obj.astype("category") | ||||
|         expected = pd.CategoricalIndex([Timedelta("1h"), Timedelta("2h")]) | ||||
|         tm.assert_index_equal(result, expected) | ||||
|  | ||||
|         result = obj._data.astype("category") | ||||
|         expected = expected.values | ||||
|         tm.assert_categorical_equal(result, expected) | ||||
|  | ||||
|     def test_astype_array_fallback(self): | ||||
|         obj = timedelta_range("1h", periods=2) | ||||
|         result = obj.astype(bool) | ||||
|         expected = Index(np.array([True, True])) | ||||
|         tm.assert_index_equal(result, expected) | ||||
|  | ||||
|         result = obj._data.astype(bool) | ||||
|         expected = np.array([True, True]) | ||||
|         tm.assert_numpy_array_equal(result, expected) | ||||
| @ -0,0 +1,40 @@ | ||||
| import numpy as np | ||||
|  | ||||
| from pandas import ( | ||||
|     TimedeltaIndex, | ||||
|     factorize, | ||||
|     timedelta_range, | ||||
| ) | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| class TestTimedeltaIndexFactorize: | ||||
|     def test_factorize(self): | ||||
|         idx1 = TimedeltaIndex(["1 day", "1 day", "2 day", "2 day", "3 day", "3 day"]) | ||||
|  | ||||
|         exp_arr = np.array([0, 0, 1, 1, 2, 2], dtype=np.intp) | ||||
|         exp_idx = TimedeltaIndex(["1 day", "2 day", "3 day"]) | ||||
|  | ||||
|         arr, idx = idx1.factorize() | ||||
|         tm.assert_numpy_array_equal(arr, exp_arr) | ||||
|         tm.assert_index_equal(idx, exp_idx) | ||||
|         assert idx.freq == exp_idx.freq | ||||
|  | ||||
|         arr, idx = idx1.factorize(sort=True) | ||||
|         tm.assert_numpy_array_equal(arr, exp_arr) | ||||
|         tm.assert_index_equal(idx, exp_idx) | ||||
|         assert idx.freq == exp_idx.freq | ||||
|  | ||||
|     def test_factorize_preserves_freq(self): | ||||
|         # GH#38120 freq should be preserved | ||||
|         idx3 = timedelta_range("1 day", periods=4, freq="s") | ||||
|         exp_arr = np.array([0, 1, 2, 3], dtype=np.intp) | ||||
|         arr, idx = idx3.factorize() | ||||
|         tm.assert_numpy_array_equal(arr, exp_arr) | ||||
|         tm.assert_index_equal(idx, idx3) | ||||
|         assert idx.freq == idx3.freq | ||||
|  | ||||
|         arr, idx = factorize(idx3) | ||||
|         tm.assert_numpy_array_equal(arr, exp_arr) | ||||
|         tm.assert_index_equal(idx, idx3) | ||||
|         assert idx.freq == idx3.freq | ||||
| @ -0,0 +1,22 @@ | ||||
| from pandas import ( | ||||
|     Index, | ||||
|     NaT, | ||||
|     Timedelta, | ||||
|     TimedeltaIndex, | ||||
| ) | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| class TestFillNA: | ||||
|     def test_fillna_timedelta(self): | ||||
|         # GH#11343 | ||||
|         idx = TimedeltaIndex(["1 day", NaT, "3 day"]) | ||||
|  | ||||
|         exp = TimedeltaIndex(["1 day", "2 day", "3 day"]) | ||||
|         tm.assert_index_equal(idx.fillna(Timedelta("2 day")), exp) | ||||
|  | ||||
|         exp = TimedeltaIndex(["1 day", "3 hour", "3 day"]) | ||||
|         idx.fillna(Timedelta("3 hour")) | ||||
|  | ||||
|         exp = Index([Timedelta("1 day"), "x", Timedelta("3 day")], dtype=object) | ||||
|         tm.assert_index_equal(idx.fillna("x"), exp) | ||||
| @ -0,0 +1,145 @@ | ||||
| from datetime import timedelta | ||||
|  | ||||
| import numpy as np | ||||
| import pytest | ||||
|  | ||||
| from pandas._libs import lib | ||||
|  | ||||
| import pandas as pd | ||||
| from pandas import ( | ||||
|     Index, | ||||
|     Timedelta, | ||||
|     TimedeltaIndex, | ||||
|     timedelta_range, | ||||
| ) | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| class TestTimedeltaIndexInsert: | ||||
|     def test_insert(self): | ||||
|         idx = TimedeltaIndex(["4day", "1day", "2day"], name="idx") | ||||
|  | ||||
|         result = idx.insert(2, timedelta(days=5)) | ||||
|         exp = TimedeltaIndex(["4day", "1day", "5day", "2day"], name="idx") | ||||
|         tm.assert_index_equal(result, exp) | ||||
|  | ||||
|         # insertion of non-datetime should coerce to object index | ||||
|         result = idx.insert(1, "inserted") | ||||
|         expected = Index( | ||||
|             [Timedelta("4day"), "inserted", Timedelta("1day"), Timedelta("2day")], | ||||
|             name="idx", | ||||
|         ) | ||||
|         assert not isinstance(result, TimedeltaIndex) | ||||
|         tm.assert_index_equal(result, expected) | ||||
|         assert result.name == expected.name | ||||
|  | ||||
|         idx = timedelta_range("1day 00:00:01", periods=3, freq="s", name="idx") | ||||
|  | ||||
|         # preserve freq | ||||
|         expected_0 = TimedeltaIndex( | ||||
|             ["1day", "1day 00:00:01", "1day 00:00:02", "1day 00:00:03"], | ||||
|             name="idx", | ||||
|             freq="s", | ||||
|         ) | ||||
|         expected_3 = TimedeltaIndex( | ||||
|             ["1day 00:00:01", "1day 00:00:02", "1day 00:00:03", "1day 00:00:04"], | ||||
|             name="idx", | ||||
|             freq="s", | ||||
|         ) | ||||
|  | ||||
|         # reset freq to None | ||||
|         expected_1_nofreq = TimedeltaIndex( | ||||
|             ["1day 00:00:01", "1day 00:00:01", "1day 00:00:02", "1day 00:00:03"], | ||||
|             name="idx", | ||||
|             freq=None, | ||||
|         ) | ||||
|         expected_3_nofreq = TimedeltaIndex( | ||||
|             ["1day 00:00:01", "1day 00:00:02", "1day 00:00:03", "1day 00:00:05"], | ||||
|             name="idx", | ||||
|             freq=None, | ||||
|         ) | ||||
|  | ||||
|         cases = [ | ||||
|             (0, Timedelta("1day"), expected_0), | ||||
|             (-3, Timedelta("1day"), expected_0), | ||||
|             (3, Timedelta("1day 00:00:04"), expected_3), | ||||
|             (1, Timedelta("1day 00:00:01"), expected_1_nofreq), | ||||
|             (3, Timedelta("1day 00:00:05"), expected_3_nofreq), | ||||
|         ] | ||||
|  | ||||
|         for n, d, expected in cases: | ||||
|             result = idx.insert(n, d) | ||||
|             tm.assert_index_equal(result, expected) | ||||
|             assert result.name == expected.name | ||||
|             assert result.freq == expected.freq | ||||
|  | ||||
|     @pytest.mark.parametrize( | ||||
|         "null", [None, np.nan, np.timedelta64("NaT"), pd.NaT, pd.NA] | ||||
|     ) | ||||
|     def test_insert_nat(self, null): | ||||
|         # GH 18295 (test missing) | ||||
|         idx = timedelta_range("1day", "3day") | ||||
|         result = idx.insert(1, null) | ||||
|         expected = TimedeltaIndex(["1day", pd.NaT, "2day", "3day"]) | ||||
|         tm.assert_index_equal(result, expected) | ||||
|  | ||||
|     def test_insert_invalid_na(self): | ||||
|         idx = TimedeltaIndex(["4day", "1day", "2day"], name="idx") | ||||
|  | ||||
|         item = np.datetime64("NaT") | ||||
|         result = idx.insert(0, item) | ||||
|  | ||||
|         expected = Index([item] + list(idx), dtype=object, name="idx") | ||||
|         tm.assert_index_equal(result, expected) | ||||
|  | ||||
|         # Also works if we pass a different dt64nat object | ||||
|         item2 = np.datetime64("NaT") | ||||
|         result = idx.insert(0, item2) | ||||
|         tm.assert_index_equal(result, expected) | ||||
|  | ||||
|     @pytest.mark.parametrize( | ||||
|         "item", [0, np.int64(0), np.float64(0), np.array(0), np.datetime64(456, "us")] | ||||
|     ) | ||||
|     def test_insert_mismatched_types_raises(self, item): | ||||
|         # GH#33703 dont cast these to td64 | ||||
|         tdi = TimedeltaIndex(["4day", "1day", "2day"], name="idx") | ||||
|  | ||||
|         result = tdi.insert(1, item) | ||||
|  | ||||
|         expected = Index( | ||||
|             [tdi[0], lib.item_from_zerodim(item)] + list(tdi[1:]), | ||||
|             dtype=object, | ||||
|             name="idx", | ||||
|         ) | ||||
|         tm.assert_index_equal(result, expected) | ||||
|  | ||||
|     def test_insert_castable_str(self): | ||||
|         idx = timedelta_range("1day", "3day") | ||||
|  | ||||
|         result = idx.insert(0, "1 Day") | ||||
|  | ||||
|         expected = TimedeltaIndex([idx[0]] + list(idx)) | ||||
|         tm.assert_index_equal(result, expected) | ||||
|  | ||||
|     def test_insert_non_castable_str(self): | ||||
|         idx = timedelta_range("1day", "3day") | ||||
|  | ||||
|         result = idx.insert(0, "foo") | ||||
|  | ||||
|         expected = Index(["foo"] + list(idx), dtype=object) | ||||
|         tm.assert_index_equal(result, expected) | ||||
|  | ||||
|     def test_insert_empty(self): | ||||
|         # Corner case inserting with length zero doesn't raise IndexError | ||||
|         # GH#33573 for freq preservation | ||||
|         idx = timedelta_range("1 Day", periods=3) | ||||
|         td = idx[0] | ||||
|  | ||||
|         result = idx[:0].insert(0, td) | ||||
|         assert result.freq == "D" | ||||
|  | ||||
|         with pytest.raises(IndexError, match="loc must be an integer between"): | ||||
|             result = idx[:0].insert(1, td) | ||||
|  | ||||
|         with pytest.raises(IndexError, match="loc must be an integer between"): | ||||
|             result = idx[:0].insert(-1, td) | ||||
| @ -0,0 +1,34 @@ | ||||
| import numpy as np | ||||
|  | ||||
| from pandas import ( | ||||
|     TimedeltaIndex, | ||||
|     timedelta_range, | ||||
| ) | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| class TestRepeat: | ||||
|     def test_repeat(self): | ||||
|         index = timedelta_range("1 days", periods=2, freq="D") | ||||
|         exp = TimedeltaIndex(["1 days", "1 days", "2 days", "2 days"]) | ||||
|         for res in [index.repeat(2), np.repeat(index, 2)]: | ||||
|             tm.assert_index_equal(res, exp) | ||||
|             assert res.freq is None | ||||
|  | ||||
|         index = TimedeltaIndex(["1 days", "NaT", "3 days"]) | ||||
|         exp = TimedeltaIndex( | ||||
|             [ | ||||
|                 "1 days", | ||||
|                 "1 days", | ||||
|                 "1 days", | ||||
|                 "NaT", | ||||
|                 "NaT", | ||||
|                 "NaT", | ||||
|                 "3 days", | ||||
|                 "3 days", | ||||
|                 "3 days", | ||||
|             ] | ||||
|         ) | ||||
|         for res in [index.repeat(3), np.repeat(index, 3)]: | ||||
|             tm.assert_index_equal(res, exp) | ||||
|             assert res.freq is None | ||||
| @ -0,0 +1,76 @@ | ||||
| import pytest | ||||
|  | ||||
| from pandas.errors import NullFrequencyError | ||||
|  | ||||
| import pandas as pd | ||||
| from pandas import TimedeltaIndex | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| class TestTimedeltaIndexShift: | ||||
|     # ------------------------------------------------------------- | ||||
|     # TimedeltaIndex.shift is used by __add__/__sub__ | ||||
|  | ||||
|     def test_tdi_shift_empty(self): | ||||
|         # GH#9903 | ||||
|         idx = TimedeltaIndex([], name="xxx") | ||||
|         tm.assert_index_equal(idx.shift(0, freq="h"), idx) | ||||
|         tm.assert_index_equal(idx.shift(3, freq="h"), idx) | ||||
|  | ||||
|     def test_tdi_shift_hours(self): | ||||
|         # GH#9903 | ||||
|         idx = TimedeltaIndex(["5 hours", "6 hours", "9 hours"], name="xxx") | ||||
|         tm.assert_index_equal(idx.shift(0, freq="h"), idx) | ||||
|         exp = TimedeltaIndex(["8 hours", "9 hours", "12 hours"], name="xxx") | ||||
|         tm.assert_index_equal(idx.shift(3, freq="h"), exp) | ||||
|         exp = TimedeltaIndex(["2 hours", "3 hours", "6 hours"], name="xxx") | ||||
|         tm.assert_index_equal(idx.shift(-3, freq="h"), exp) | ||||
|  | ||||
|     def test_tdi_shift_minutes(self): | ||||
|         # GH#9903 | ||||
|         idx = TimedeltaIndex(["5 hours", "6 hours", "9 hours"], name="xxx") | ||||
|         tm.assert_index_equal(idx.shift(0, freq="min"), idx) | ||||
|         exp = TimedeltaIndex(["05:03:00", "06:03:00", "9:03:00"], name="xxx") | ||||
|         tm.assert_index_equal(idx.shift(3, freq="min"), exp) | ||||
|         exp = TimedeltaIndex(["04:57:00", "05:57:00", "8:57:00"], name="xxx") | ||||
|         tm.assert_index_equal(idx.shift(-3, freq="min"), exp) | ||||
|  | ||||
|     def test_tdi_shift_int(self): | ||||
|         # GH#8083 | ||||
|         tdi = pd.to_timedelta(range(5), unit="d") | ||||
|         trange = tdi._with_freq("infer") + pd.offsets.Hour(1) | ||||
|         result = trange.shift(1) | ||||
|         expected = TimedeltaIndex( | ||||
|             [ | ||||
|                 "1 days 01:00:00", | ||||
|                 "2 days 01:00:00", | ||||
|                 "3 days 01:00:00", | ||||
|                 "4 days 01:00:00", | ||||
|                 "5 days 01:00:00", | ||||
|             ], | ||||
|             freq="D", | ||||
|         ) | ||||
|         tm.assert_index_equal(result, expected) | ||||
|  | ||||
|     def test_tdi_shift_nonstandard_freq(self): | ||||
|         # GH#8083 | ||||
|         tdi = pd.to_timedelta(range(5), unit="d") | ||||
|         trange = tdi._with_freq("infer") + pd.offsets.Hour(1) | ||||
|         result = trange.shift(3, freq="2D 1s") | ||||
|         expected = TimedeltaIndex( | ||||
|             [ | ||||
|                 "6 days 01:00:03", | ||||
|                 "7 days 01:00:03", | ||||
|                 "8 days 01:00:03", | ||||
|                 "9 days 01:00:03", | ||||
|                 "10 days 01:00:03", | ||||
|             ], | ||||
|             freq="D", | ||||
|         ) | ||||
|         tm.assert_index_equal(result, expected) | ||||
|  | ||||
|     def test_shift_no_freq(self): | ||||
|         # GH#19147 | ||||
|         tdi = TimedeltaIndex(["1 days 01:00:00", "2 days 01:00:00"], freq=None) | ||||
|         with pytest.raises(NullFrequencyError, match="Cannot shift with no freq"): | ||||
|             tdi.shift(2) | ||||
		Reference in New Issue
	
	Block a user