Skip to content

Commit

Permalink
CLN: standardize fixture usage in datetimelike array tests (#36902)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrockmendel committed Oct 6, 2020
1 parent 880b361 commit f8e0ecb
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 98 deletions.
132 changes: 63 additions & 69 deletions pandas/tests/arrays/test_datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,37 +17,40 @@

# TODO: more freq variants
@pytest.fixture(params=["D", "B", "W", "M", "Q", "Y"])
def period_index(request):
def freqstr(request):
return request.param


@pytest.fixture
def period_index(freqstr):
"""
A fixture to provide PeriodIndex objects with different frequencies.
Most PeriodArray behavior is already tested in PeriodIndex tests,
so here we just test that the PeriodArray behavior matches
the PeriodIndex behavior.
"""
freqstr = request.param
# TODO: non-monotone indexes; NaTs, different start dates
pi = pd.period_range(start=pd.Timestamp("2000-01-01"), periods=100, freq=freqstr)
return pi


@pytest.fixture(params=["D", "B", "W", "M", "Q", "Y"])
def datetime_index(request):
@pytest.fixture
def datetime_index(freqstr):
"""
A fixture to provide DatetimeIndex objects with different frequencies.
Most DatetimeArray behavior is already tested in DatetimeIndex tests,
so here we just test that the DatetimeArray behavior matches
the DatetimeIndex behavior.
"""
freqstr = request.param
# TODO: non-monotone indexes; NaTs, different start dates, timezones
dti = pd.date_range(start=pd.Timestamp("2000-01-01"), periods=100, freq=freqstr)
return dti


@pytest.fixture
def timedelta_index(request):
def timedelta_index():
"""
A fixture to provide TimedeltaIndex objects with different frequencies.
Most TimedeltaArray behavior is already tested in TimedeltaIndex tests,
Expand Down Expand Up @@ -448,16 +451,15 @@ class TestDatetimeArray(SharedTests):
dtype = pd.Timestamp

@pytest.fixture
def arr1d(self, tz_naive_fixture):
def arr1d(self, tz_naive_fixture, freqstr):
tz = tz_naive_fixture
dti = pd.date_range("2016-01-01 01:01:00", periods=3, freq="H", tz=tz)
dti = pd.date_range("2016-01-01 01:01:00", periods=3, freq=freqstr, tz=tz)
dta = dti._data
return dta

def test_round(self, tz_naive_fixture):
def test_round(self, arr1d):
# GH#24064
tz = tz_naive_fixture
dti = pd.date_range("2016-01-01 01:01:00", periods=3, freq="H", tz=tz)
dti = self.index_cls(arr1d)

result = dti.round(freq="2T")
expected = dti - pd.Timedelta(minutes=1)
Expand Down Expand Up @@ -511,11 +513,10 @@ def test_array_interface(self, datetime_index):
expected = np.asarray(arr).astype(dtype)
tm.assert_numpy_array_equal(result, expected)

def test_array_object_dtype(self, tz_naive_fixture):
def test_array_object_dtype(self, arr1d):
# GH#23524
tz = tz_naive_fixture
dti = pd.date_range("2016-01-01", periods=3, tz=tz)
arr = DatetimeArray(dti)
arr = arr1d
dti = self.index_cls(arr1d)

expected = np.array(list(dti))

Expand All @@ -526,11 +527,10 @@ def test_array_object_dtype(self, tz_naive_fixture):
result = np.array(dti, dtype=object)
tm.assert_numpy_array_equal(result, expected)

def test_array_tz(self, tz_naive_fixture):
def test_array_tz(self, arr1d):
# GH#23524
tz = tz_naive_fixture
dti = pd.date_range("2016-01-01", periods=3, tz=tz)
arr = DatetimeArray(dti)
arr = arr1d
dti = self.index_cls(arr1d)

expected = dti.asi8.view("M8[ns]")
result = np.array(arr, dtype="M8[ns]")
Expand All @@ -547,10 +547,9 @@ def test_array_tz(self, tz_naive_fixture):
assert result.base is expected.base
assert result.base is not None

def test_array_i8_dtype(self, tz_naive_fixture):
tz = tz_naive_fixture
dti = pd.date_range("2016-01-01", periods=3, tz=tz)
arr = DatetimeArray(dti)
def test_array_i8_dtype(self, arr1d):
arr = arr1d
dti = self.index_cls(arr1d)

expected = dti.asi8
result = np.array(arr, dtype="i8")
Expand All @@ -573,27 +572,25 @@ def test_from_array_keeps_base(self):
dta = DatetimeArray(arr[:0])
assert dta._data.base is arr

def test_from_dti(self, tz_naive_fixture):
tz = tz_naive_fixture
dti = pd.date_range("2016-01-01", periods=3, tz=tz)
arr = DatetimeArray(dti)
def test_from_dti(self, arr1d):
arr = arr1d
dti = self.index_cls(arr1d)
assert list(dti) == list(arr)

# Check that Index.__new__ knows what to do with DatetimeArray
dti2 = pd.Index(arr)
assert isinstance(dti2, pd.DatetimeIndex)
assert list(dti2) == list(arr)

def test_astype_object(self, tz_naive_fixture):
tz = tz_naive_fixture
dti = pd.date_range("2016-01-01", periods=3, tz=tz)
arr = DatetimeArray(dti)
def test_astype_object(self, arr1d):
arr = arr1d
dti = self.index_cls(arr1d)

asobj = arr.astype("O")
assert isinstance(asobj, np.ndarray)
assert asobj.dtype == "O"
assert list(asobj) == list(dti)

@pytest.mark.parametrize("freqstr", ["D", "B", "W", "M", "Q", "Y"])
def test_to_perioddelta(self, datetime_index, freqstr):
# GH#23113
dti = datetime_index
Expand All @@ -612,7 +609,6 @@ def test_to_perioddelta(self, datetime_index, freqstr):
# an EA-specific tm.assert_ function
tm.assert_index_equal(pd.Index(result), pd.Index(expected))

@pytest.mark.parametrize("freqstr", ["D", "B", "W", "M", "Q", "Y"])
def test_to_period(self, datetime_index, freqstr):
dti = datetime_index
arr = DatetimeArray(dti)
Expand All @@ -626,10 +622,10 @@ def test_to_period(self, datetime_index, freqstr):
tm.assert_index_equal(pd.Index(result), pd.Index(expected))

@pytest.mark.parametrize("propname", pd.DatetimeIndex._bool_ops)
def test_bool_properties(self, datetime_index, propname):
def test_bool_properties(self, arr1d, propname):
# in this case _bool_ops is just `is_leap_year`
dti = datetime_index
arr = DatetimeArray(dti)
dti = self.index_cls(arr1d)
arr = arr1d
assert dti.freq == arr.freq

result = getattr(arr, propname)
Expand All @@ -638,21 +634,21 @@ def test_bool_properties(self, datetime_index, propname):
tm.assert_numpy_array_equal(result, expected)

@pytest.mark.parametrize("propname", pd.DatetimeIndex._field_ops)
def test_int_properties(self, datetime_index, propname):
def test_int_properties(self, arr1d, propname):
if propname in ["week", "weekofyear"]:
# GH#33595 Deprecate week and weekofyear
return
dti = datetime_index
arr = DatetimeArray(dti)
dti = self.index_cls(arr1d)
arr = arr1d

result = getattr(arr, propname)
expected = np.array(getattr(dti, propname), dtype=result.dtype)

tm.assert_numpy_array_equal(result, expected)

def test_take_fill_valid(self, datetime_index, tz_naive_fixture):
dti = datetime_index.tz_localize(tz_naive_fixture)
arr = DatetimeArray(dti)
def test_take_fill_valid(self, arr1d):
arr = arr1d
dti = self.index_cls(arr1d)

now = pd.Timestamp.now().tz_localize(dti.tz)
result = arr.take([-1, 1], allow_fill=True, fill_value=now)
Expand Down Expand Up @@ -687,10 +683,9 @@ def test_take_fill_valid(self, datetime_index, tz_naive_fixture):
# require appropriate-dtype if we have a NA value
arr.take([-1, 1], allow_fill=True, fill_value=value)

def test_concat_same_type_invalid(self, datetime_index):
def test_concat_same_type_invalid(self, arr1d):
# different timezones
dti = datetime_index
arr = DatetimeArray(dti)
arr = arr1d

if arr.tz is None:
other = arr.tz_localize("UTC")
Expand Down Expand Up @@ -718,8 +713,8 @@ def test_concat_same_type_different_freq(self):

tm.assert_datetime_array_equal(result, expected)

def test_strftime(self, datetime_index):
arr = DatetimeArray(datetime_index)
def test_strftime(self, arr1d):
arr = arr1d

result = arr.strftime("%Y %b")
expected = np.array([ts.strftime("%Y %b") for ts in arr], dtype=object)
Expand Down Expand Up @@ -864,27 +859,26 @@ class TestPeriodArray(SharedTests):
def arr1d(self, period_index):
return period_index._data

def test_from_pi(self, period_index):
pi = period_index
arr = PeriodArray(pi)
def test_from_pi(self, arr1d):
pi = self.index_cls(arr1d)
arr = arr1d
assert list(arr) == list(pi)

# Check that Index.__new__ knows what to do with PeriodArray
pi2 = pd.Index(arr)
assert isinstance(pi2, pd.PeriodIndex)
assert list(pi2) == list(arr)

def test_astype_object(self, period_index):
pi = period_index
arr = PeriodArray(pi)
def test_astype_object(self, arr1d):
pi = self.index_cls(arr1d)
arr = arr1d
asobj = arr.astype("O")
assert isinstance(asobj, np.ndarray)
assert asobj.dtype == "O"
assert list(asobj) == list(pi)

def test_take_fill_valid(self, period_index):
pi = period_index
arr = PeriodArray(pi)
def test_take_fill_valid(self, arr1d):
arr = arr1d

value = pd.NaT.value
msg = f"'fill_value' should be a {self.dtype}. Got '{value}'."
Expand All @@ -899,9 +893,9 @@ def test_take_fill_valid(self, period_index):
arr.take([-1, 1], allow_fill=True, fill_value=value)

@pytest.mark.parametrize("how", ["S", "E"])
def test_to_timestamp(self, how, period_index):
pi = period_index
arr = PeriodArray(pi)
def test_to_timestamp(self, how, arr1d):
pi = self.index_cls(arr1d)
arr = arr1d

expected = DatetimeArray(pi.to_timestamp(how=how))
result = arr.to_timestamp(how=how)
Expand All @@ -922,28 +916,28 @@ def test_to_timestamp_out_of_bounds(self):
pi._data.to_timestamp()

@pytest.mark.parametrize("propname", PeriodArray._bool_ops)
def test_bool_properties(self, period_index, propname):
def test_bool_properties(self, arr1d, propname):
# in this case _bool_ops is just `is_leap_year`
pi = period_index
arr = PeriodArray(pi)
pi = self.index_cls(arr1d)
arr = arr1d

result = getattr(arr, propname)
expected = np.array(getattr(pi, propname))

tm.assert_numpy_array_equal(result, expected)

@pytest.mark.parametrize("propname", PeriodArray._field_ops)
def test_int_properties(self, period_index, propname):
pi = period_index
arr = PeriodArray(pi)
def test_int_properties(self, arr1d, propname):
pi = self.index_cls(arr1d)
arr = arr1d

result = getattr(arr, propname)
expected = np.array(getattr(pi, propname))

tm.assert_numpy_array_equal(result, expected)

def test_array_interface(self, period_index):
arr = PeriodArray(period_index)
def test_array_interface(self, arr1d):
arr = arr1d

# default asarray gives objects
result = np.asarray(arr)
Expand All @@ -966,8 +960,8 @@ def test_array_interface(self, period_index):
expected = np.asarray(arr).astype("S20")
tm.assert_numpy_array_equal(result, expected)

def test_strftime(self, period_index):
arr = PeriodArray(period_index)
def test_strftime(self, arr1d):
arr = arr1d

result = arr.strftime("%Y")
expected = np.array([per.strftime("%Y") for per in arr], dtype=object)
Expand Down
61 changes: 32 additions & 29 deletions pandas/tests/arrays/test_timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def test_copy(self):


class TestTimedeltaArray:
# TODO: de-duplicate with test_npsum below
def test_np_sum(self):
# GH#25282
vals = np.arange(5, dtype=np.int64).view("m8[h]").astype("m8[ns]")
Expand All @@ -76,35 +77,6 @@ def test_from_sequence_dtype(self):
with pytest.raises(ValueError, match=msg):
TimedeltaArray._from_sequence([], dtype=object)

def test_abs(self):
vals = np.array([-3600 * 10 ** 9, "NaT", 7200 * 10 ** 9], dtype="m8[ns]")
arr = TimedeltaArray(vals)

evals = np.array([3600 * 10 ** 9, "NaT", 7200 * 10 ** 9], dtype="m8[ns]")
expected = TimedeltaArray(evals)

result = abs(arr)
tm.assert_timedelta_array_equal(result, expected)

def test_neg(self):
vals = np.array([-3600 * 10 ** 9, "NaT", 7200 * 10 ** 9], dtype="m8[ns]")
arr = TimedeltaArray(vals)

evals = np.array([3600 * 10 ** 9, "NaT", -7200 * 10 ** 9], dtype="m8[ns]")
expected = TimedeltaArray(evals)

result = -arr
tm.assert_timedelta_array_equal(result, expected)

def test_neg_freq(self):
tdi = pd.timedelta_range("2 Days", periods=4, freq="H")
arr = TimedeltaArray(tdi, freq=tdi.freq)

expected = TimedeltaArray(-tdi._data, freq=-tdi.freq)

result = -arr
tm.assert_timedelta_array_equal(result, expected)

@pytest.mark.parametrize("dtype", [int, np.int32, np.int64, "uint32", "uint64"])
def test_astype_int(self, dtype):
arr = TimedeltaArray._from_sequence([pd.Timedelta("1H"), pd.Timedelta("2H")])
Expand Down Expand Up @@ -171,6 +143,37 @@ def test_searchsorted_invalid_types(self, other, index):
arr.searchsorted(other)


class TestUnaryOps:
def test_abs(self):
vals = np.array([-3600 * 10 ** 9, "NaT", 7200 * 10 ** 9], dtype="m8[ns]")
arr = TimedeltaArray(vals)

evals = np.array([3600 * 10 ** 9, "NaT", 7200 * 10 ** 9], dtype="m8[ns]")
expected = TimedeltaArray(evals)

result = abs(arr)
tm.assert_timedelta_array_equal(result, expected)

def test_neg(self):
vals = np.array([-3600 * 10 ** 9, "NaT", 7200 * 10 ** 9], dtype="m8[ns]")
arr = TimedeltaArray(vals)

evals = np.array([3600 * 10 ** 9, "NaT", -7200 * 10 ** 9], dtype="m8[ns]")
expected = TimedeltaArray(evals)

result = -arr
tm.assert_timedelta_array_equal(result, expected)

def test_neg_freq(self):
tdi = pd.timedelta_range("2 Days", periods=4, freq="H")
arr = TimedeltaArray(tdi, freq=tdi.freq)

expected = TimedeltaArray(-tdi._data, freq=-tdi.freq)

result = -arr
tm.assert_timedelta_array_equal(result, expected)


class TestReductions:
@pytest.mark.parametrize("name", ["sum", "std", "min", "max", "median"])
@pytest.mark.parametrize("skipna", [True, False])
Expand Down

0 comments on commit f8e0ecb

Please sign in to comment.