123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- import numpy as np
- import pytest
- from pandas.core.dtypes.dtypes import DatetimeTZDtype
- import pandas as pd
- from pandas import NaT
- import pandas._testing as tm
- from pandas.core.arrays import DatetimeArray
- class TestReductions:
- @pytest.fixture(params=["s", "ms", "us", "ns"])
- def unit(self, request):
- return request.param
- @pytest.fixture
- def arr1d(self, tz_naive_fixture):
- """Fixture returning DatetimeArray with parametrized timezones"""
- tz = tz_naive_fixture
- dtype = DatetimeTZDtype(tz=tz) if tz is not None else np.dtype("M8[ns]")
- arr = DatetimeArray._from_sequence(
- [
- "2000-01-03",
- "2000-01-03",
- "NaT",
- "2000-01-02",
- "2000-01-05",
- "2000-01-04",
- ],
- dtype=dtype,
- )
- return arr
- def test_min_max(self, arr1d, unit):
- arr = arr1d
- arr = arr.as_unit(unit)
- tz = arr.tz
- result = arr.min()
- expected = pd.Timestamp("2000-01-02", tz=tz).as_unit(unit)
- assert result == expected
- assert result.unit == expected.unit
- result = arr.max()
- expected = pd.Timestamp("2000-01-05", tz=tz).as_unit(unit)
- assert result == expected
- assert result.unit == expected.unit
- result = arr.min(skipna=False)
- assert result is NaT
- result = arr.max(skipna=False)
- assert result is NaT
- @pytest.mark.parametrize("tz", [None, "US/Central"])
- @pytest.mark.parametrize("skipna", [True, False])
- def test_min_max_empty(self, skipna, tz):
- dtype = DatetimeTZDtype(tz=tz) if tz is not None else np.dtype("M8[ns]")
- arr = DatetimeArray._from_sequence([], dtype=dtype)
- result = arr.min(skipna=skipna)
- assert result is NaT
- result = arr.max(skipna=skipna)
- assert result is NaT
- @pytest.mark.parametrize("tz", [None, "US/Central"])
- @pytest.mark.parametrize("skipna", [True, False])
- def test_median_empty(self, skipna, tz):
- dtype = DatetimeTZDtype(tz=tz) if tz is not None else np.dtype("M8[ns]")
- arr = DatetimeArray._from_sequence([], dtype=dtype)
- result = arr.median(skipna=skipna)
- assert result is NaT
- arr = arr.reshape(0, 3)
- result = arr.median(axis=0, skipna=skipna)
- expected = type(arr)._from_sequence([NaT, NaT, NaT], dtype=arr.dtype)
- tm.assert_equal(result, expected)
- result = arr.median(axis=1, skipna=skipna)
- expected = type(arr)._from_sequence([], dtype=arr.dtype)
- tm.assert_equal(result, expected)
- def test_median(self, arr1d):
- arr = arr1d
- result = arr.median()
- assert result == arr[0]
- result = arr.median(skipna=False)
- assert result is NaT
- result = arr.dropna().median(skipna=False)
- assert result == arr[0]
- result = arr.median(axis=0)
- assert result == arr[0]
- def test_median_axis(self, arr1d):
- arr = arr1d
- assert arr.median(axis=0) == arr.median()
- assert arr.median(axis=0, skipna=False) is NaT
- msg = r"abs\(axis\) must be less than ndim"
- with pytest.raises(ValueError, match=msg):
- arr.median(axis=1)
- @pytest.mark.filterwarnings("ignore:All-NaN slice encountered:RuntimeWarning")
- def test_median_2d(self, arr1d):
- arr = arr1d.reshape(1, -1)
- # axis = None
- assert arr.median() == arr1d.median()
- assert arr.median(skipna=False) is NaT
- # axis = 0
- result = arr.median(axis=0)
- expected = arr1d
- tm.assert_equal(result, expected)
- # Since column 3 is all-NaT, we get NaT there with or without skipna
- result = arr.median(axis=0, skipna=False)
- expected = arr1d
- tm.assert_equal(result, expected)
- # axis = 1
- result = arr.median(axis=1)
- expected = type(arr)._from_sequence([arr1d.median()])
- tm.assert_equal(result, expected)
- result = arr.median(axis=1, skipna=False)
- expected = type(arr)._from_sequence([NaT], dtype=arr.dtype)
- tm.assert_equal(result, expected)
- def test_mean(self, arr1d):
- arr = arr1d
- # manually verified result
- expected = arr[0] + 0.4 * pd.Timedelta(days=1)
- result = arr.mean()
- assert result == expected
- result = arr.mean(skipna=False)
- assert result is NaT
- result = arr.dropna().mean(skipna=False)
- assert result == expected
- result = arr.mean(axis=0)
- assert result == expected
- def test_mean_2d(self):
- dti = pd.date_range("2016-01-01", periods=6, tz="US/Pacific")
- dta = dti._data.reshape(3, 2)
- result = dta.mean(axis=0)
- expected = dta[1]
- tm.assert_datetime_array_equal(result, expected)
- result = dta.mean(axis=1)
- expected = dta[:, 0] + pd.Timedelta(hours=12)
- tm.assert_datetime_array_equal(result, expected)
- result = dta.mean(axis=None)
- expected = dti.mean()
- assert result == expected
- @pytest.mark.parametrize("skipna", [True, False])
- def test_mean_empty(self, arr1d, skipna):
- arr = arr1d[:0]
- assert arr.mean(skipna=skipna) is NaT
- arr2d = arr.reshape(0, 3)
- result = arr2d.mean(axis=0, skipna=skipna)
- expected = DatetimeArray._from_sequence([NaT, NaT, NaT], dtype=arr.dtype)
- tm.assert_datetime_array_equal(result, expected)
- result = arr2d.mean(axis=1, skipna=skipna)
- expected = arr # i.e. 1D, empty
- tm.assert_datetime_array_equal(result, expected)
- result = arr2d.mean(axis=None, skipna=skipna)
- assert result is NaT
|