Skip to content

Followup Cleanup DTI test_arithmetic, ASV #19149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jan 10, 2018
3 changes: 0 additions & 3 deletions asv_bench/benchmarks/timestamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ def setup(self, tz, freq):
def time_tz(self, tz, freq):
self.ts.tz

def time_offset(self, tz, freq):
self.ts.offset

def time_dayofweek(self, tz, freq):
self.ts.dayofweek

Expand Down
186 changes: 105 additions & 81 deletions pandas/tests/indexes/datetimes/test_arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,111 @@ def test_dti_with_offset_series(self, tz, names):
tm.assert_series_equal(res3, expected_sub)


@pytest.mark.parametrize('klass,assert_func', [
(Series, tm.assert_series_equal),
(DatetimeIndex, tm.assert_index_equal)])
def test_dt64_with_offset_array(klass, assert_func):
# GH#10699
# array of offsets
box = Series if klass is Series else pd.Index
with tm.assert_produces_warning(PerformanceWarning):
s = klass([Timestamp('2000-1-1'), Timestamp('2000-2-1')])
result = s + box([pd.offsets.DateOffset(years=1),
pd.offsets.MonthEnd()])
exp = klass([Timestamp('2001-1-1'), Timestamp('2000-2-29')])
assert_func(result, exp)

# same offset
result = s + box([pd.offsets.DateOffset(years=1),
pd.offsets.DateOffset(years=1)])
exp = klass([Timestamp('2001-1-1'), Timestamp('2001-2-1')])
assert_func(result, exp)


@pytest.mark.parametrize('klass,assert_func', [
(Series, tm.assert_series_equal),
(DatetimeIndex, tm.assert_index_equal)])
def test_dt64_with_DateOffsets_relativedelta(klass, assert_func):
# GH#10699
vec = klass([Timestamp('2000-01-05 00:15:00'),
Timestamp('2000-01-31 00:23:00'),
Timestamp('2000-01-01'),
Timestamp('2000-03-31'),
Timestamp('2000-02-29'),
Timestamp('2000-12-31'),
Timestamp('2000-05-15'),
Timestamp('2001-06-15')])

# DateOffset relativedelta fastpath
relative_kwargs = [('years', 2), ('months', 5), ('days', 3),
('hours', 5), ('minutes', 10), ('seconds', 2),
('microseconds', 5)]
for i, kwd in enumerate(relative_kwargs):
op = pd.DateOffset(**dict([kwd]))
assert_func(klass([x + op for x in vec]), vec + op)
assert_func(klass([x - op for x in vec]), vec - op)
op = pd.DateOffset(**dict(relative_kwargs[:i + 1]))
assert_func(klass([x + op for x in vec]), vec + op)
assert_func(klass([x - op for x in vec]), vec - op)


@pytest.mark.parametrize('cls_name', [
'YearBegin', ('YearBegin', {'month': 5}),
'YearEnd', ('YearEnd', {'month': 5}),
'MonthBegin', 'MonthEnd',
'SemiMonthEnd', 'SemiMonthBegin',
'Week', ('Week', {'weekday': 3}),
'BusinessDay', 'BDay', 'QuarterEnd', 'QuarterBegin',
'CustomBusinessDay', 'CDay', 'CBMonthEnd',
'CBMonthBegin', 'BMonthBegin', 'BMonthEnd',
'BusinessHour', 'BYearBegin', 'BYearEnd',
'BQuarterBegin', ('LastWeekOfMonth', {'weekday': 2}),
('FY5253Quarter', {'qtr_with_extra_week': 1,
'startingMonth': 1,
'weekday': 2,
'variation': 'nearest'}),
('FY5253', {'weekday': 0, 'startingMonth': 2, 'variation': 'nearest'}),
('WeekOfMonth', {'weekday': 2, 'week': 2}),
'Easter', ('DateOffset', {'day': 4}),
('DateOffset', {'month': 5})])
@pytest.mark.parametrize('normalize', [True, False])
@pytest.mark.parametrize('klass,assert_func', [
(Series, tm.assert_series_equal),
(DatetimeIndex, tm.assert_index_equal)])
def test_dt64_with_DateOffsets(klass, assert_func, normalize, cls_name):
# GH#10699
# assert these are equal on a piecewise basis
vec = klass([Timestamp('2000-01-05 00:15:00'),
Timestamp('2000-01-31 00:23:00'),
Timestamp('2000-01-01'),
Timestamp('2000-03-31'),
Timestamp('2000-02-29'),
Timestamp('2000-12-31'),
Timestamp('2000-05-15'),
Timestamp('2001-06-15')])

if isinstance(cls_name, tuple):
# If cls_name param is a tuple, then 2nd entry is kwargs for
# the offset constructor
cls_name, kwargs = cls_name
else:
kwargs = {}

offset_cls = getattr(pd.offsets, cls_name)

with warnings.catch_warnings(record=True):
for n in [0, 5]:
if (cls_name in ['WeekOfMonth', 'LastWeekOfMonth',
'FY5253Quarter', 'FY5253'] and n == 0):
# passing n = 0 is invalid for these offset classes
continue

offset = offset_cls(n, normalize=normalize, **kwargs)
assert_func(klass([x + offset for x in vec]), vec + offset)
assert_func(klass([x - offset for x in vec]), vec - offset)
assert_func(klass([offset + x for x in vec]), offset + vec)


# GH 10699
@pytest.mark.parametrize('klass,assert_func', zip([Series, DatetimeIndex],
[tm.assert_series_equal,
Expand Down Expand Up @@ -480,84 +585,3 @@ def test_datetime64_with_DateOffset(klass, assert_func):
Timestamp('2000-02-29', tz='US/Central')], name='a')
assert_func(result, exp)
assert_func(result2, exp)

# array of offsets - valid for Series only
if klass is Series:
with tm.assert_produces_warning(PerformanceWarning):
s = klass([Timestamp('2000-1-1'), Timestamp('2000-2-1')])
result = s + Series([pd.offsets.DateOffset(years=1),
pd.offsets.MonthEnd()])
exp = klass([Timestamp('2001-1-1'), Timestamp('2000-2-29')
])
assert_func(result, exp)

# same offset
result = s + Series([pd.offsets.DateOffset(years=1),
pd.offsets.DateOffset(years=1)])
exp = klass([Timestamp('2001-1-1'), Timestamp('2001-2-1')])
assert_func(result, exp)

s = klass([Timestamp('2000-01-05 00:15:00'),
Timestamp('2000-01-31 00:23:00'),
Timestamp('2000-01-01'),
Timestamp('2000-03-31'),
Timestamp('2000-02-29'),
Timestamp('2000-12-31'),
Timestamp('2000-05-15'),
Timestamp('2001-06-15')])

# DateOffset relativedelta fastpath
relative_kwargs = [('years', 2), ('months', 5), ('days', 3),
('hours', 5), ('minutes', 10), ('seconds', 2),
('microseconds', 5)]
for i, kwd in enumerate(relative_kwargs):
op = pd.DateOffset(**dict([kwd]))
assert_func(klass([x + op for x in s]), s + op)
assert_func(klass([x - op for x in s]), s - op)
op = pd.DateOffset(**dict(relative_kwargs[:i + 1]))
assert_func(klass([x + op for x in s]), s + op)
assert_func(klass([x - op for x in s]), s - op)

# assert these are equal on a piecewise basis
offsets = ['YearBegin', ('YearBegin', {'month': 5}),
'YearEnd', ('YearEnd', {'month': 5}),
'MonthBegin', 'MonthEnd',
'SemiMonthEnd', 'SemiMonthBegin',
'Week', ('Week', {'weekday': 3}),
'BusinessDay', 'BDay', 'QuarterEnd', 'QuarterBegin',
'CustomBusinessDay', 'CDay', 'CBMonthEnd',
'CBMonthBegin', 'BMonthBegin', 'BMonthEnd',
'BusinessHour', 'BYearBegin', 'BYearEnd',
'BQuarterBegin', ('LastWeekOfMonth', {'weekday': 2}),
('FY5253Quarter', {'qtr_with_extra_week': 1,
'startingMonth': 1,
'weekday': 2,
'variation': 'nearest'}),
('FY5253', {'weekday': 0,
'startingMonth': 2,
'variation':
'nearest'}),
('WeekOfMonth', {'weekday': 2,
'week': 2}),
'Easter', ('DateOffset', {'day': 4}),
('DateOffset', {'month': 5})]

with warnings.catch_warnings(record=True):
for normalize in (True, False):
for do in offsets:
if isinstance(do, tuple):
do, kwargs = do
else:
do = do
kwargs = {}

for n in [0, 5]:
Copy link
Member Author

@jbrockmendel jbrockmendel Jan 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure that this for n in [0, 5]: down through line 563557 is intended to have one fewer level of indentation. That change is implemented up in test_dt64_with_DateOffsets.

if (do in ['WeekOfMonth', 'LastWeekOfMonth',
'FY5253Quarter', 'FY5253'] and n == 0):
continue
op = getattr(pd.offsets, do)(n,
normalize=normalize,
**kwargs)
assert_func(klass([x + op for x in s]), s + op)
assert_func(klass([x - op for x in s]), s - op)
assert_func(klass([op + x for x in s]), op + s)
149 changes: 75 additions & 74 deletions pandas/tests/series/test_operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -1005,9 +1005,7 @@ def test_operators_timedelta64_with_timedelta_invalid(self, scalar_td):

@pytest.mark.parametrize('scalar_td', [
timedelta(minutes=5, seconds=4),
pytest.param(Timedelta('5m4s'),
marks=pytest.mark.xfail(reason="Timedelta.__floordiv__ "
"bug GH#18846")),
Timedelta('5m4s'),
Timedelta('5m4s').to_timedelta64()])
def test_timedelta_rfloordiv(self, scalar_td):
# GH#18831
Expand Down Expand Up @@ -1381,21 +1379,23 @@ def test_datetime64_ops_nat(self):
assert_series_equal(NaT + nat_series_dtype_timestamp,
nat_series_dtype_timestamp)

@pytest.mark.parametrize('dt64_series', [
Series([Timestamp('19900315'), Timestamp('19900315')]),
Series([NaT, Timestamp('19900315')]),
Series([NaT, NaT], dtype='datetime64[ns]')])
@pytest.mark.parametrize('one', [1, 1.0, np.array(1)])
def test_dt64_mul_div_numeric_invalid(self, one, dt64_series):
# multiplication
with pytest.raises(TypeError):
datetime_series * 1
with pytest.raises(TypeError):
nat_series_dtype_timestamp * 1
dt64_series * one
with pytest.raises(TypeError):
datetime_series * 1.0
with pytest.raises(TypeError):
nat_series_dtype_timestamp * 1.0
one * dt64_series

# division
with pytest.raises(TypeError):
nat_series_dtype_timestamp / 1.0
dt64_series / one
with pytest.raises(TypeError):
nat_series_dtype_timestamp / 1
one / dt64_series

def test_dt64series_arith_overflow(self):
# GH#12534, fixed by #19024
Expand Down Expand Up @@ -1574,6 +1574,7 @@ def test_timedelta64_conversions(self):
expected = s1.apply(
lambda x: Timedelta(np.timedelta64(m, unit)) / x)
result = np.timedelta64(m, unit) / s1
assert_series_equal(result, expected)

# astype
s = Series(date_range('20130101', periods=3))
Expand Down Expand Up @@ -1990,69 +1991,69 @@ def test_series_frame_radd_bug(self):
with pytest.raises(TypeError):
self.ts + datetime.now()

def test_series_radd_more(self):
data = [[1, 2, 3],
[1.1, 2.2, 3.3],
[pd.Timestamp('2011-01-01'), pd.Timestamp('2011-01-02'),
pd.NaT],
['x', 'y', 1]]

for d in data:
for dtype in [None, object]:
s = Series(d, dtype=dtype)
with pytest.raises(TypeError):
'foo_' + s

for dtype in [None, object]:
res = 1 + pd.Series([1, 2, 3], dtype=dtype)
exp = pd.Series([2, 3, 4], dtype=dtype)
assert_series_equal(res, exp)
res = pd.Series([1, 2, 3], dtype=dtype) + 1
assert_series_equal(res, exp)

res = np.nan + pd.Series([1, 2, 3], dtype=dtype)
exp = pd.Series([np.nan, np.nan, np.nan], dtype=dtype)
assert_series_equal(res, exp)
res = pd.Series([1, 2, 3], dtype=dtype) + np.nan
assert_series_equal(res, exp)

s = pd.Series([pd.Timedelta('1 days'), pd.Timedelta('2 days'),
pd.Timedelta('3 days')], dtype=dtype)
exp = pd.Series([pd.Timedelta('4 days'), pd.Timedelta('5 days'),
pd.Timedelta('6 days')])
assert_series_equal(pd.Timedelta('3 days') + s, exp)
assert_series_equal(s + pd.Timedelta('3 days'), exp)

s = pd.Series(['x', np.nan, 'x'])
assert_series_equal('a' + s, pd.Series(['ax', np.nan, 'ax']))
assert_series_equal(s + 'a', pd.Series(['xa', np.nan, 'xa']))

def test_frame_radd_more(self):
data = [[1, 2, 3],
[1.1, 2.2, 3.3],
[pd.Timestamp('2011-01-01'), pd.Timestamp('2011-01-02'),
pd.NaT],
['x', 'y', 1]]

for d in data:
for dtype in [None, object]:
s = DataFrame(d, dtype=dtype)
with pytest.raises(TypeError):
'foo_' + s

for dtype in [None, object]:
res = 1 + pd.DataFrame([1, 2, 3], dtype=dtype)
exp = pd.DataFrame([2, 3, 4], dtype=dtype)
assert_frame_equal(res, exp)
res = pd.DataFrame([1, 2, 3], dtype=dtype) + 1
assert_frame_equal(res, exp)

res = np.nan + pd.DataFrame([1, 2, 3], dtype=dtype)
exp = pd.DataFrame([np.nan, np.nan, np.nan], dtype=dtype)
assert_frame_equal(res, exp)
res = pd.DataFrame([1, 2, 3], dtype=dtype) + np.nan
assert_frame_equal(res, exp)

def test_series_radd_str(self):
ser = pd.Series(['x', np.nan, 'x'])
assert_series_equal('a' + ser, pd.Series(['ax', np.nan, 'ax']))
assert_series_equal(ser + 'a', pd.Series(['xa', np.nan, 'xa']))

@pytest.mark.parametrize('dtype', [None, object])
def test_series_radd_more(self, dtype):
res = 1 + pd.Series([1, 2, 3], dtype=dtype)
exp = pd.Series([2, 3, 4], dtype=dtype)
assert_series_equal(res, exp)
res = pd.Series([1, 2, 3], dtype=dtype) + 1
assert_series_equal(res, exp)

res = np.nan + pd.Series([1, 2, 3], dtype=dtype)
exp = pd.Series([np.nan, np.nan, np.nan], dtype=dtype)
assert_series_equal(res, exp)
res = pd.Series([1, 2, 3], dtype=dtype) + np.nan
assert_series_equal(res, exp)

s = pd.Series([pd.Timedelta('1 days'), pd.Timedelta('2 days'),
pd.Timedelta('3 days')], dtype=dtype)
exp = pd.Series([pd.Timedelta('4 days'), pd.Timedelta('5 days'),
pd.Timedelta('6 days')])
assert_series_equal(pd.Timedelta('3 days') + s, exp)
assert_series_equal(s + pd.Timedelta('3 days'), exp)

@pytest.mark.parametrize('data', [
[1, 2, 3],
[1.1, 2.2, 3.3],
[pd.Timestamp('2011-01-01'), pd.Timestamp('2011-01-02'), pd.NaT],
['x', 'y', 1]])
@pytest.mark.parametrize('dtype', [None, object])
def test_series_radd_str_invalid(self, dtype, data):
ser = Series(data, dtype=dtype)
with pytest.raises(TypeError):
'foo_' + ser

@pytest.mark.parametrize('data', [
[1, 2, 3],
[1.1, 2.2, 3.3],
[pd.Timestamp('2011-01-01'), pd.Timestamp('2011-01-02'), pd.NaT],
['x', 'y', 1]])
@pytest.mark.parametrize('dtype', [None, object])
def test_frame_radd_str_invalid(self, dtype, data):
df = DataFrame(data, dtype=dtype)
with pytest.raises(TypeError):
'foo_' + df

@pytest.mark.parametrize('dtype', [None, object])
def test_frame_radd_more(self, dtype):
res = 1 + pd.DataFrame([1, 2, 3], dtype=dtype)
exp = pd.DataFrame([2, 3, 4], dtype=dtype)
assert_frame_equal(res, exp)
res = pd.DataFrame([1, 2, 3], dtype=dtype) + 1
assert_frame_equal(res, exp)

res = np.nan + pd.DataFrame([1, 2, 3], dtype=dtype)
exp = pd.DataFrame([np.nan, np.nan, np.nan], dtype=dtype)
assert_frame_equal(res, exp)
res = pd.DataFrame([1, 2, 3], dtype=dtype) + np.nan
assert_frame_equal(res, exp)

def test_frame_radd_str(self):
df = pd.DataFrame(['x', np.nan, 'x'])
assert_frame_equal('a' + df, pd.DataFrame(['ax', np.nan, 'ax']))
assert_frame_equal(df + 'a', pd.DataFrame(['xa', np.nan, 'xa']))
Expand Down