done
This commit is contained in:
		| @ -0,0 +1,103 @@ | ||||
| import numpy as np | ||||
| import pytest | ||||
|  | ||||
| import pandas._testing as tm | ||||
| from pandas.core.arrays import TimedeltaArray | ||||
|  | ||||
|  | ||||
| class TestTimedeltaArrayConstructor: | ||||
|     def test_only_1dim_accepted(self): | ||||
|         # GH#25282 | ||||
|         arr = np.array([0, 1, 2, 3], dtype="m8[h]").astype("m8[ns]") | ||||
|  | ||||
|         depr_msg = "TimedeltaArray.__init__ is deprecated" | ||||
|         with tm.assert_produces_warning(FutureWarning, match=depr_msg): | ||||
|             with pytest.raises(ValueError, match="Only 1-dimensional"): | ||||
|                 # 3-dim, we allow 2D to sneak in for ops purposes GH#29853 | ||||
|                 TimedeltaArray(arr.reshape(2, 2, 1)) | ||||
|  | ||||
|         with tm.assert_produces_warning(FutureWarning, match=depr_msg): | ||||
|             with pytest.raises(ValueError, match="Only 1-dimensional"): | ||||
|                 # 0-dim | ||||
|                 TimedeltaArray(arr[[0]].squeeze()) | ||||
|  | ||||
|     def test_freq_validation(self): | ||||
|         # ensure that the public constructor cannot create an invalid instance | ||||
|         arr = np.array([0, 0, 1], dtype=np.int64) * 3600 * 10**9 | ||||
|  | ||||
|         msg = ( | ||||
|             "Inferred frequency None from passed values does not " | ||||
|             "conform to passed frequency D" | ||||
|         ) | ||||
|         depr_msg = "TimedeltaArray.__init__ is deprecated" | ||||
|         with tm.assert_produces_warning(FutureWarning, match=depr_msg): | ||||
|             with pytest.raises(ValueError, match=msg): | ||||
|                 TimedeltaArray(arr.view("timedelta64[ns]"), freq="D") | ||||
|  | ||||
|     def test_non_array_raises(self): | ||||
|         depr_msg = "TimedeltaArray.__init__ is deprecated" | ||||
|         with tm.assert_produces_warning(FutureWarning, match=depr_msg): | ||||
|             with pytest.raises(ValueError, match="list"): | ||||
|                 TimedeltaArray([1, 2, 3]) | ||||
|  | ||||
|     def test_other_type_raises(self): | ||||
|         msg = r"dtype bool cannot be converted to timedelta64\[ns\]" | ||||
|         with pytest.raises(TypeError, match=msg): | ||||
|             TimedeltaArray._from_sequence(np.array([1, 2, 3], dtype="bool")) | ||||
|  | ||||
|     def test_incorrect_dtype_raises(self): | ||||
|         msg = "dtype 'category' is invalid, should be np.timedelta64 dtype" | ||||
|         with pytest.raises(ValueError, match=msg): | ||||
|             TimedeltaArray._from_sequence( | ||||
|                 np.array([1, 2, 3], dtype="i8"), dtype="category" | ||||
|             ) | ||||
|  | ||||
|         msg = "dtype 'int64' is invalid, should be np.timedelta64 dtype" | ||||
|         with pytest.raises(ValueError, match=msg): | ||||
|             TimedeltaArray._from_sequence( | ||||
|                 np.array([1, 2, 3], dtype="i8"), dtype=np.dtype("int64") | ||||
|             ) | ||||
|  | ||||
|         msg = r"dtype 'datetime64\[ns\]' is invalid, should be np.timedelta64 dtype" | ||||
|         with pytest.raises(ValueError, match=msg): | ||||
|             TimedeltaArray._from_sequence( | ||||
|                 np.array([1, 2, 3], dtype="i8"), dtype=np.dtype("M8[ns]") | ||||
|             ) | ||||
|  | ||||
|         msg = ( | ||||
|             r"dtype 'datetime64\[us, UTC\]' is invalid, should be np.timedelta64 dtype" | ||||
|         ) | ||||
|         with pytest.raises(ValueError, match=msg): | ||||
|             TimedeltaArray._from_sequence( | ||||
|                 np.array([1, 2, 3], dtype="i8"), dtype="M8[us, UTC]" | ||||
|             ) | ||||
|  | ||||
|         msg = "Supported timedelta64 resolutions are 's', 'ms', 'us', 'ns'" | ||||
|         with pytest.raises(ValueError, match=msg): | ||||
|             TimedeltaArray._from_sequence( | ||||
|                 np.array([1, 2, 3], dtype="i8"), dtype=np.dtype("m8[Y]") | ||||
|             ) | ||||
|  | ||||
|     def test_mismatched_values_dtype_units(self): | ||||
|         arr = np.array([1, 2, 3], dtype="m8[s]") | ||||
|         dtype = np.dtype("m8[ns]") | ||||
|         msg = r"Values resolution does not match dtype" | ||||
|         depr_msg = "TimedeltaArray.__init__ is deprecated" | ||||
|  | ||||
|         with tm.assert_produces_warning(FutureWarning, match=depr_msg): | ||||
|             with pytest.raises(ValueError, match=msg): | ||||
|                 TimedeltaArray(arr, dtype=dtype) | ||||
|  | ||||
|     def test_copy(self): | ||||
|         data = np.array([1, 2, 3], dtype="m8[ns]") | ||||
|         arr = TimedeltaArray._from_sequence(data, copy=False) | ||||
|         assert arr._ndarray is data | ||||
|  | ||||
|         arr = TimedeltaArray._from_sequence(data, copy=True) | ||||
|         assert arr._ndarray is not data | ||||
|         assert arr._ndarray.base is not data | ||||
|  | ||||
|     def test_from_sequence_dtype(self): | ||||
|         msg = "dtype 'object' is invalid, should be np.timedelta64 dtype" | ||||
|         with pytest.raises(ValueError, match=msg): | ||||
|             TimedeltaArray._from_sequence([], dtype=object) | ||||
| @ -0,0 +1,20 @@ | ||||
| import pytest | ||||
|  | ||||
| import pandas._testing as tm | ||||
| from pandas.core.arrays import TimedeltaArray | ||||
|  | ||||
|  | ||||
| class TestAccumulator: | ||||
|     def test_accumulators_disallowed(self): | ||||
|         # GH#50297 | ||||
|         arr = TimedeltaArray._from_sequence(["1D", "2D"], dtype="m8[ns]") | ||||
|         with pytest.raises(TypeError, match="cumprod not supported"): | ||||
|             arr._accumulate("cumprod") | ||||
|  | ||||
|     def test_cumsum(self, unit): | ||||
|         # GH#50297 | ||||
|         dtype = f"m8[{unit}]" | ||||
|         arr = TimedeltaArray._from_sequence(["1D", "2D"], dtype=dtype) | ||||
|         result = arr._accumulate("cumsum") | ||||
|         expected = TimedeltaArray._from_sequence(["1D", "3D"], dtype=dtype) | ||||
|         tm.assert_timedelta_array_equal(result, expected) | ||||
| @ -0,0 +1,218 @@ | ||||
| import numpy as np | ||||
| import pytest | ||||
|  | ||||
| import pandas as pd | ||||
| from pandas import Timedelta | ||||
| import pandas._testing as tm | ||||
| from pandas.core import nanops | ||||
| from pandas.core.arrays import TimedeltaArray | ||||
|  | ||||
|  | ||||
| class TestReductions: | ||||
|     @pytest.mark.parametrize("name", ["std", "min", "max", "median", "mean"]) | ||||
|     @pytest.mark.parametrize("skipna", [True, False]) | ||||
|     def test_reductions_empty(self, name, skipna): | ||||
|         tdi = pd.TimedeltaIndex([]) | ||||
|         arr = tdi.array | ||||
|  | ||||
|         result = getattr(tdi, name)(skipna=skipna) | ||||
|         assert result is pd.NaT | ||||
|  | ||||
|         result = getattr(arr, name)(skipna=skipna) | ||||
|         assert result is pd.NaT | ||||
|  | ||||
|     @pytest.mark.parametrize("skipna", [True, False]) | ||||
|     def test_sum_empty(self, skipna): | ||||
|         tdi = pd.TimedeltaIndex([]) | ||||
|         arr = tdi.array | ||||
|  | ||||
|         result = tdi.sum(skipna=skipna) | ||||
|         assert isinstance(result, Timedelta) | ||||
|         assert result == Timedelta(0) | ||||
|  | ||||
|         result = arr.sum(skipna=skipna) | ||||
|         assert isinstance(result, Timedelta) | ||||
|         assert result == Timedelta(0) | ||||
|  | ||||
|     def test_min_max(self, unit): | ||||
|         dtype = f"m8[{unit}]" | ||||
|         arr = TimedeltaArray._from_sequence( | ||||
|             ["3h", "3h", "NaT", "2h", "5h", "4h"], dtype=dtype | ||||
|         ) | ||||
|  | ||||
|         result = arr.min() | ||||
|         expected = Timedelta("2h") | ||||
|         assert result == expected | ||||
|  | ||||
|         result = arr.max() | ||||
|         expected = Timedelta("5h") | ||||
|         assert result == expected | ||||
|  | ||||
|         result = arr.min(skipna=False) | ||||
|         assert result is pd.NaT | ||||
|  | ||||
|         result = arr.max(skipna=False) | ||||
|         assert result is pd.NaT | ||||
|  | ||||
|     def test_sum(self): | ||||
|         tdi = pd.TimedeltaIndex(["3h", "3h", "NaT", "2h", "5h", "4h"]) | ||||
|         arr = tdi.array | ||||
|  | ||||
|         result = arr.sum(skipna=True) | ||||
|         expected = Timedelta(hours=17) | ||||
|         assert isinstance(result, Timedelta) | ||||
|         assert result == expected | ||||
|  | ||||
|         result = tdi.sum(skipna=True) | ||||
|         assert isinstance(result, Timedelta) | ||||
|         assert result == expected | ||||
|  | ||||
|         result = arr.sum(skipna=False) | ||||
|         assert result is pd.NaT | ||||
|  | ||||
|         result = tdi.sum(skipna=False) | ||||
|         assert result is pd.NaT | ||||
|  | ||||
|         result = arr.sum(min_count=9) | ||||
|         assert result is pd.NaT | ||||
|  | ||||
|         result = tdi.sum(min_count=9) | ||||
|         assert result is pd.NaT | ||||
|  | ||||
|         result = arr.sum(min_count=1) | ||||
|         assert isinstance(result, Timedelta) | ||||
|         assert result == expected | ||||
|  | ||||
|         result = tdi.sum(min_count=1) | ||||
|         assert isinstance(result, Timedelta) | ||||
|         assert result == expected | ||||
|  | ||||
|     def test_npsum(self): | ||||
|         # GH#25282, GH#25335 np.sum should return a Timedelta, not timedelta64 | ||||
|         tdi = pd.TimedeltaIndex(["3h", "3h", "2h", "5h", "4h"]) | ||||
|         arr = tdi.array | ||||
|  | ||||
|         result = np.sum(tdi) | ||||
|         expected = Timedelta(hours=17) | ||||
|         assert isinstance(result, Timedelta) | ||||
|         assert result == expected | ||||
|  | ||||
|         result = np.sum(arr) | ||||
|         assert isinstance(result, Timedelta) | ||||
|         assert result == expected | ||||
|  | ||||
|     def test_sum_2d_skipna_false(self): | ||||
|         arr = np.arange(8).astype(np.int64).view("m8[s]").astype("m8[ns]").reshape(4, 2) | ||||
|         arr[-1, -1] = "Nat" | ||||
|  | ||||
|         tda = TimedeltaArray._from_sequence(arr) | ||||
|  | ||||
|         result = tda.sum(skipna=False) | ||||
|         assert result is pd.NaT | ||||
|  | ||||
|         result = tda.sum(axis=0, skipna=False) | ||||
|         expected = pd.TimedeltaIndex([Timedelta(seconds=12), pd.NaT])._values | ||||
|         tm.assert_timedelta_array_equal(result, expected) | ||||
|  | ||||
|         result = tda.sum(axis=1, skipna=False) | ||||
|         expected = pd.TimedeltaIndex( | ||||
|             [ | ||||
|                 Timedelta(seconds=1), | ||||
|                 Timedelta(seconds=5), | ||||
|                 Timedelta(seconds=9), | ||||
|                 pd.NaT, | ||||
|             ] | ||||
|         )._values | ||||
|         tm.assert_timedelta_array_equal(result, expected) | ||||
|  | ||||
|     # Adding a Timestamp makes this a test for DatetimeArray.std | ||||
|     @pytest.mark.parametrize( | ||||
|         "add", | ||||
|         [ | ||||
|             Timedelta(0), | ||||
|             pd.Timestamp("2021-01-01"), | ||||
|             pd.Timestamp("2021-01-01", tz="UTC"), | ||||
|             pd.Timestamp("2021-01-01", tz="Asia/Tokyo"), | ||||
|         ], | ||||
|     ) | ||||
|     def test_std(self, add): | ||||
|         tdi = pd.TimedeltaIndex(["0h", "4h", "NaT", "4h", "0h", "2h"]) + add | ||||
|         arr = tdi.array | ||||
|  | ||||
|         result = arr.std(skipna=True) | ||||
|         expected = Timedelta(hours=2) | ||||
|         assert isinstance(result, Timedelta) | ||||
|         assert result == expected | ||||
|  | ||||
|         result = tdi.std(skipna=True) | ||||
|         assert isinstance(result, Timedelta) | ||||
|         assert result == expected | ||||
|  | ||||
|         if getattr(arr, "tz", None) is None: | ||||
|             result = nanops.nanstd(np.asarray(arr), skipna=True) | ||||
|             assert isinstance(result, np.timedelta64) | ||||
|             assert result == expected | ||||
|  | ||||
|         result = arr.std(skipna=False) | ||||
|         assert result is pd.NaT | ||||
|  | ||||
|         result = tdi.std(skipna=False) | ||||
|         assert result is pd.NaT | ||||
|  | ||||
|         if getattr(arr, "tz", None) is None: | ||||
|             result = nanops.nanstd(np.asarray(arr), skipna=False) | ||||
|             assert isinstance(result, np.timedelta64) | ||||
|             assert np.isnat(result) | ||||
|  | ||||
|     def test_median(self): | ||||
|         tdi = pd.TimedeltaIndex(["0h", "3h", "NaT", "5h06m", "0h", "2h"]) | ||||
|         arr = tdi.array | ||||
|  | ||||
|         result = arr.median(skipna=True) | ||||
|         expected = Timedelta(hours=2) | ||||
|         assert isinstance(result, Timedelta) | ||||
|         assert result == expected | ||||
|  | ||||
|         result = tdi.median(skipna=True) | ||||
|         assert isinstance(result, Timedelta) | ||||
|         assert result == expected | ||||
|  | ||||
|         result = arr.median(skipna=False) | ||||
|         assert result is pd.NaT | ||||
|  | ||||
|         result = tdi.median(skipna=False) | ||||
|         assert result is pd.NaT | ||||
|  | ||||
|     def test_mean(self): | ||||
|         tdi = pd.TimedeltaIndex(["0h", "3h", "NaT", "5h06m", "0h", "2h"]) | ||||
|         arr = tdi._data | ||||
|  | ||||
|         # manually verified result | ||||
|         expected = Timedelta(arr.dropna()._ndarray.mean()) | ||||
|  | ||||
|         result = arr.mean() | ||||
|         assert result == expected | ||||
|         result = arr.mean(skipna=False) | ||||
|         assert result is pd.NaT | ||||
|  | ||||
|         result = arr.dropna().mean(skipna=False) | ||||
|         assert result == expected | ||||
|  | ||||
|         result = arr.mean(axis=0) | ||||
|         assert result == expected | ||||
|  | ||||
|     def test_mean_2d(self): | ||||
|         tdi = pd.timedelta_range("14 days", periods=6) | ||||
|         tda = tdi._data.reshape(3, 2) | ||||
|  | ||||
|         result = tda.mean(axis=0) | ||||
|         expected = tda[1] | ||||
|         tm.assert_timedelta_array_equal(result, expected) | ||||
|  | ||||
|         result = tda.mean(axis=1) | ||||
|         expected = tda[:, 0] + Timedelta(hours=12) | ||||
|         tm.assert_timedelta_array_equal(result, expected) | ||||
|  | ||||
|         result = tda.mean(axis=None) | ||||
|         expected = tdi.mean() | ||||
|         assert result == expected | ||||
		Reference in New Issue
	
	Block a user