1123 lines
42 KiB
Python
1123 lines
42 KiB
Python
# -*- coding: utf-8 -*-
|
|
import operator
|
|
|
|
import pytest
|
|
import numpy as np
|
|
from datetime import timedelta
|
|
from distutils.version import LooseVersion
|
|
|
|
import pandas as pd
|
|
import pandas.util.testing as tm
|
|
from pandas import (DatetimeIndex, TimedeltaIndex, Float64Index, Int64Index,
|
|
to_timedelta, timedelta_range, date_range,
|
|
Series,
|
|
Timestamp, Timedelta)
|
|
from pandas.errors import PerformanceWarning, NullFrequencyError
|
|
from pandas.core import ops
|
|
|
|
|
|
@pytest.fixture(params=[pd.offsets.Hour(2), timedelta(hours=2),
|
|
np.timedelta64(2, 'h'), Timedelta(hours=2)],
|
|
ids=str)
|
|
def delta(request):
|
|
# Several ways of representing two hours
|
|
return request.param
|
|
|
|
|
|
@pytest.fixture(params=['B', 'D'])
|
|
def freq(request):
|
|
return request.param
|
|
|
|
|
|
class TestTimedeltaIndexComparisons(object):
|
|
def test_tdi_cmp_str_invalid(self):
|
|
# GH 13624
|
|
tdi = TimedeltaIndex(['1 day', '2 days'])
|
|
|
|
for left, right in [(tdi, 'a'), ('a', tdi)]:
|
|
with pytest.raises(TypeError):
|
|
left > right
|
|
|
|
with pytest.raises(TypeError):
|
|
left == right
|
|
|
|
with pytest.raises(TypeError):
|
|
left != right
|
|
|
|
def test_comparisons_coverage(self):
|
|
rng = timedelta_range('1 days', periods=10)
|
|
|
|
result = rng < rng[3]
|
|
exp = np.array([True, True, True] + [False] * 7)
|
|
tm.assert_numpy_array_equal(result, exp)
|
|
|
|
# raise TypeError for now
|
|
pytest.raises(TypeError, rng.__lt__, rng[3].value)
|
|
|
|
result = rng == list(rng)
|
|
exp = rng == rng
|
|
tm.assert_numpy_array_equal(result, exp)
|
|
|
|
def test_comp_nat(self):
|
|
left = pd.TimedeltaIndex([pd.Timedelta('1 days'), pd.NaT,
|
|
pd.Timedelta('3 days')])
|
|
right = pd.TimedeltaIndex([pd.NaT, pd.NaT, pd.Timedelta('3 days')])
|
|
|
|
for lhs, rhs in [(left, right),
|
|
(left.astype(object), right.astype(object))]:
|
|
result = rhs == lhs
|
|
expected = np.array([False, False, True])
|
|
tm.assert_numpy_array_equal(result, expected)
|
|
|
|
result = rhs != lhs
|
|
expected = np.array([True, True, False])
|
|
tm.assert_numpy_array_equal(result, expected)
|
|
|
|
expected = np.array([False, False, False])
|
|
tm.assert_numpy_array_equal(lhs == pd.NaT, expected)
|
|
tm.assert_numpy_array_equal(pd.NaT == rhs, expected)
|
|
|
|
expected = np.array([True, True, True])
|
|
tm.assert_numpy_array_equal(lhs != pd.NaT, expected)
|
|
tm.assert_numpy_array_equal(pd.NaT != lhs, expected)
|
|
|
|
expected = np.array([False, False, False])
|
|
tm.assert_numpy_array_equal(lhs < pd.NaT, expected)
|
|
tm.assert_numpy_array_equal(pd.NaT > lhs, expected)
|
|
|
|
def test_comparisons_nat(self):
|
|
tdidx1 = pd.TimedeltaIndex(['1 day', pd.NaT, '1 day 00:00:01', pd.NaT,
|
|
'1 day 00:00:01', '5 day 00:00:03'])
|
|
tdidx2 = pd.TimedeltaIndex(['2 day', '2 day', pd.NaT, pd.NaT,
|
|
'1 day 00:00:02', '5 days 00:00:03'])
|
|
tdarr = np.array([np.timedelta64(2, 'D'),
|
|
np.timedelta64(2, 'D'), np.timedelta64('nat'),
|
|
np.timedelta64('nat'),
|
|
np.timedelta64(1, 'D') + np.timedelta64(2, 's'),
|
|
np.timedelta64(5, 'D') + np.timedelta64(3, 's')])
|
|
|
|
cases = [(tdidx1, tdidx2), (tdidx1, tdarr)]
|
|
|
|
# Check pd.NaT is handles as the same as np.nan
|
|
for idx1, idx2 in cases:
|
|
|
|
result = idx1 < idx2
|
|
expected = np.array([True, False, False, False, True, False])
|
|
tm.assert_numpy_array_equal(result, expected)
|
|
|
|
result = idx2 > idx1
|
|
expected = np.array([True, False, False, False, True, False])
|
|
tm.assert_numpy_array_equal(result, expected)
|
|
|
|
result = idx1 <= idx2
|
|
expected = np.array([True, False, False, False, True, True])
|
|
tm.assert_numpy_array_equal(result, expected)
|
|
|
|
result = idx2 >= idx1
|
|
expected = np.array([True, False, False, False, True, True])
|
|
tm.assert_numpy_array_equal(result, expected)
|
|
|
|
result = idx1 == idx2
|
|
expected = np.array([False, False, False, False, False, True])
|
|
tm.assert_numpy_array_equal(result, expected)
|
|
|
|
result = idx1 != idx2
|
|
expected = np.array([True, True, True, True, True, False])
|
|
tm.assert_numpy_array_equal(result, expected)
|
|
|
|
|
|
class TestTimedeltaIndexMultiplicationDivision(object):
|
|
# __mul__, __rmul__,
|
|
# __div__, __rdiv__, __floordiv__, __rfloordiv__,
|
|
# __mod__, __rmod__, __divmod__, __rdivmod__
|
|
|
|
# -------------------------------------------------------------
|
|
# Multiplication
|
|
# organized with scalar others first, then array-like
|
|
|
|
def test_tdi_mul_int(self):
|
|
idx = TimedeltaIndex(np.arange(5, dtype='int64'))
|
|
result = idx * 1
|
|
tm.assert_index_equal(result, idx)
|
|
|
|
def test_tdi_rmul_int(self):
|
|
idx = TimedeltaIndex(np.arange(5, dtype='int64'))
|
|
result = 1 * idx
|
|
tm.assert_index_equal(result, idx)
|
|
|
|
def test_tdi_mul_tdlike_scalar_raises(self, delta):
|
|
rng = timedelta_range('1 days', '10 days', name='foo')
|
|
with pytest.raises(TypeError):
|
|
rng * delta
|
|
|
|
def test_tdi_mul_int_array_zerodim(self):
|
|
rng5 = np.arange(5, dtype='int64')
|
|
idx = TimedeltaIndex(rng5)
|
|
expected = TimedeltaIndex(rng5 * 5)
|
|
result = idx * np.array(5, dtype='int64')
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
def test_tdi_mul_int_array(self):
|
|
rng5 = np.arange(5, dtype='int64')
|
|
idx = TimedeltaIndex(rng5)
|
|
didx = TimedeltaIndex(rng5 ** 2)
|
|
|
|
result = idx * rng5
|
|
tm.assert_index_equal(result, didx)
|
|
|
|
def test_tdi_mul_dti_raises(self):
|
|
idx = TimedeltaIndex(np.arange(5, dtype='int64'))
|
|
with pytest.raises(TypeError):
|
|
idx * idx
|
|
|
|
def test_tdi_mul_too_short_raises(self):
|
|
idx = TimedeltaIndex(np.arange(5, dtype='int64'))
|
|
with pytest.raises(TypeError):
|
|
idx * TimedeltaIndex(np.arange(3))
|
|
with pytest.raises(ValueError):
|
|
idx * np.array([1, 2])
|
|
|
|
def test_tdi_mul_int_series(self):
|
|
idx = TimedeltaIndex(np.arange(5, dtype='int64'))
|
|
didx = TimedeltaIndex(np.arange(5, dtype='int64') ** 2)
|
|
|
|
result = idx * Series(np.arange(5, dtype='int64'))
|
|
|
|
tm.assert_series_equal(result, Series(didx))
|
|
|
|
def test_tdi_mul_float_series(self):
|
|
idx = TimedeltaIndex(np.arange(5, dtype='int64'))
|
|
|
|
rng5f = np.arange(5, dtype='float64')
|
|
result = idx * Series(rng5f + 0.1)
|
|
expected = Series(TimedeltaIndex(rng5f * (rng5f + 0.1)))
|
|
tm.assert_series_equal(result, expected)
|
|
|
|
@pytest.mark.parametrize('other', [np.arange(1, 11),
|
|
pd.Int64Index(range(1, 11)),
|
|
pd.UInt64Index(range(1, 11)),
|
|
pd.Float64Index(range(1, 11)),
|
|
pd.RangeIndex(1, 11)])
|
|
def test_tdi_rmul_arraylike(self, other):
|
|
tdi = TimedeltaIndex(['1 Day'] * 10)
|
|
expected = timedelta_range('1 days', '10 days')
|
|
|
|
result = other * tdi
|
|
tm.assert_index_equal(result, expected)
|
|
commute = tdi * other
|
|
tm.assert_index_equal(commute, expected)
|
|
|
|
# -------------------------------------------------------------
|
|
# TimedeltaIndex.__div__
|
|
|
|
def test_tdi_div_int(self):
|
|
idx = TimedeltaIndex(np.arange(5, dtype='int64'))
|
|
result = idx / 1
|
|
tm.assert_index_equal(result, idx)
|
|
|
|
def test_tdi_div_tdlike_scalar(self, delta):
|
|
rng = timedelta_range('1 days', '10 days', name='foo')
|
|
expected = Int64Index((np.arange(10) + 1) * 12, name='foo')
|
|
|
|
result = rng / delta
|
|
tm.assert_index_equal(result, expected, exact=False)
|
|
|
|
def test_tdi_div_tdlike_scalar_with_nat(self, delta):
|
|
rng = TimedeltaIndex(['1 days', pd.NaT, '2 days'], name='foo')
|
|
expected = Float64Index([12, np.nan, 24], name='foo')
|
|
result = rng / delta
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
def test_tdi_div_nat_raises(self):
|
|
# don't allow division by NaT (make could in the future)
|
|
rng = timedelta_range('1 days', '10 days', name='foo')
|
|
with pytest.raises(TypeError):
|
|
rng / pd.NaT
|
|
|
|
# -------------------------------------------------------------
|
|
# TimedeltaIndex.__floordiv__
|
|
|
|
def test_tdi_floordiv_int(self):
|
|
idx = TimedeltaIndex(np.arange(5, dtype='int64'))
|
|
result = idx // 1
|
|
tm.assert_index_equal(result, idx)
|
|
|
|
def test_tdi_floordiv_tdlike_scalar(self, delta):
|
|
tdi = timedelta_range('1 days', '10 days', name='foo')
|
|
expected = Int64Index((np.arange(10) + 1) * 12, name='foo')
|
|
|
|
result = tdi // delta
|
|
tm.assert_index_equal(result, expected, exact=False)
|
|
|
|
@pytest.mark.parametrize('scalar_td', [
|
|
timedelta(minutes=10, seconds=7),
|
|
Timedelta('10m7s'),
|
|
Timedelta('10m7s').to_timedelta64()])
|
|
def test_tdi_floordiv_timedelta_scalar(self, scalar_td):
|
|
# GH#19125
|
|
tdi = TimedeltaIndex(['00:05:03', '00:05:03', pd.NaT], freq=None)
|
|
expected = pd.Index([2.0, 2.0, np.nan])
|
|
|
|
res = tdi.__rfloordiv__(scalar_td)
|
|
tm.assert_index_equal(res, expected)
|
|
|
|
expected = pd.Index([0.0, 0.0, np.nan])
|
|
|
|
res = tdi // (scalar_td)
|
|
tm.assert_index_equal(res, expected)
|
|
|
|
|
|
class TestTimedeltaIndexArithmetic(object):
|
|
# Addition and Subtraction Operations
|
|
|
|
# -------------------------------------------------------------
|
|
# Invalid Operations
|
|
|
|
@pytest.mark.parametrize('other', [3.14, np.array([2.0, 3.0])])
|
|
@pytest.mark.parametrize('op', [operator.add, ops.radd,
|
|
operator.sub, ops.rsub])
|
|
def test_tdi_add_sub_float(self, op, other):
|
|
dti = DatetimeIndex(['2011-01-01', '2011-01-02'], freq='D')
|
|
tdi = dti - dti.shift(1)
|
|
with pytest.raises(TypeError):
|
|
op(tdi, other)
|
|
|
|
def test_tdi_add_str_invalid(self):
|
|
# GH 13624
|
|
tdi = TimedeltaIndex(['1 day', '2 days'])
|
|
|
|
with pytest.raises(TypeError):
|
|
tdi + 'a'
|
|
with pytest.raises(TypeError):
|
|
'a' + tdi
|
|
|
|
@pytest.mark.parametrize('freq', [None, 'H'])
|
|
def test_tdi_sub_period(self, freq):
|
|
# GH#13078
|
|
# not supported, check TypeError
|
|
p = pd.Period('2011-01-01', freq='D')
|
|
|
|
idx = pd.TimedeltaIndex(['1 hours', '2 hours'], freq=freq)
|
|
|
|
with pytest.raises(TypeError):
|
|
idx - p
|
|
|
|
with pytest.raises(TypeError):
|
|
p - idx
|
|
|
|
# -------------------------------------------------------------
|
|
# TimedeltaIndex.shift is used by __add__/__sub__
|
|
|
|
def test_tdi_shift_empty(self):
|
|
# GH#9903
|
|
idx = pd.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 = pd.TimedeltaIndex(['5 hours', '6 hours', '9 hours'], name='xxx')
|
|
tm.assert_index_equal(idx.shift(0, freq='H'), idx)
|
|
exp = pd.TimedeltaIndex(['8 hours', '9 hours', '12 hours'], name='xxx')
|
|
tm.assert_index_equal(idx.shift(3, freq='H'), exp)
|
|
exp = pd.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 = pd.TimedeltaIndex(['5 hours', '6 hours', '9 hours'], name='xxx')
|
|
tm.assert_index_equal(idx.shift(0, freq='T'), idx)
|
|
exp = pd.TimedeltaIndex(['05:03:00', '06:03:00', '9:03:00'],
|
|
name='xxx')
|
|
tm.assert_index_equal(idx.shift(3, freq='T'), exp)
|
|
exp = pd.TimedeltaIndex(['04:57:00', '05:57:00', '8:57:00'],
|
|
name='xxx')
|
|
tm.assert_index_equal(idx.shift(-3, freq='T'), exp)
|
|
|
|
def test_tdi_shift_int(self):
|
|
# GH#8083
|
|
trange = pd.to_timedelta(range(5), unit='d') + 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
|
|
trange = pd.to_timedelta(range(5), unit='d') + 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):
|
|
tdi.shift(2)
|
|
|
|
# -------------------------------------------------------------
|
|
|
|
@pytest.mark.parametrize('names', [(None, None, None),
|
|
('foo', 'bar', None),
|
|
('foo', 'foo', 'foo')])
|
|
def test_tdi_add_offset_index(self, names):
|
|
# GH#18849, GH#19744
|
|
tdi = TimedeltaIndex(['1 days 00:00:00', '3 days 04:00:00'],
|
|
name=names[0])
|
|
other = pd.Index([pd.offsets.Hour(n=1), pd.offsets.Minute(n=-2)],
|
|
name=names[1])
|
|
|
|
expected = TimedeltaIndex([tdi[n] + other[n] for n in range(len(tdi))],
|
|
freq='infer', name=names[2])
|
|
|
|
with tm.assert_produces_warning(PerformanceWarning):
|
|
res = tdi + other
|
|
tm.assert_index_equal(res, expected)
|
|
|
|
with tm.assert_produces_warning(PerformanceWarning):
|
|
res2 = other + tdi
|
|
tm.assert_index_equal(res2, expected)
|
|
|
|
def test_tdi_add_offset_array(self):
|
|
# GH#18849
|
|
tdi = TimedeltaIndex(['1 days 00:00:00', '3 days 04:00:00'])
|
|
other = np.array([pd.offsets.Hour(n=1), pd.offsets.Minute(n=-2)])
|
|
|
|
expected = TimedeltaIndex([tdi[n] + other[n] for n in range(len(tdi))],
|
|
freq='infer')
|
|
|
|
with tm.assert_produces_warning(PerformanceWarning):
|
|
res = tdi + other
|
|
tm.assert_index_equal(res, expected)
|
|
|
|
with tm.assert_produces_warning(PerformanceWarning):
|
|
res2 = other + tdi
|
|
tm.assert_index_equal(res2, expected)
|
|
|
|
@pytest.mark.parametrize('names', [(None, None, None),
|
|
('foo', 'bar', None),
|
|
('foo', 'foo', 'foo')])
|
|
def test_tdi_sub_offset_index(self, names):
|
|
# GH#18824, GH#19744
|
|
tdi = TimedeltaIndex(['1 days 00:00:00', '3 days 04:00:00'],
|
|
name=names[0])
|
|
other = pd.Index([pd.offsets.Hour(n=1), pd.offsets.Minute(n=-2)],
|
|
name=names[1])
|
|
|
|
expected = TimedeltaIndex([tdi[n] - other[n] for n in range(len(tdi))],
|
|
freq='infer', name=names[2])
|
|
|
|
with tm.assert_produces_warning(PerformanceWarning):
|
|
res = tdi - other
|
|
tm.assert_index_equal(res, expected)
|
|
|
|
def test_tdi_sub_offset_array(self):
|
|
# GH#18824
|
|
tdi = TimedeltaIndex(['1 days 00:00:00', '3 days 04:00:00'])
|
|
other = np.array([pd.offsets.Hour(n=1), pd.offsets.Minute(n=-2)])
|
|
|
|
expected = TimedeltaIndex([tdi[n] - other[n] for n in range(len(tdi))],
|
|
freq='infer')
|
|
|
|
with tm.assert_produces_warning(PerformanceWarning):
|
|
res = tdi - other
|
|
tm.assert_index_equal(res, expected)
|
|
|
|
@pytest.mark.parametrize('names', [(None, None, None),
|
|
('foo', 'bar', None),
|
|
('foo', 'foo', 'foo')])
|
|
def test_tdi_with_offset_series(self, names):
|
|
# GH#18849
|
|
tdi = TimedeltaIndex(['1 days 00:00:00', '3 days 04:00:00'],
|
|
name=names[0])
|
|
other = Series([pd.offsets.Hour(n=1), pd.offsets.Minute(n=-2)],
|
|
name=names[1])
|
|
|
|
expected_add = Series([tdi[n] + other[n] for n in range(len(tdi))],
|
|
name=names[2])
|
|
|
|
with tm.assert_produces_warning(PerformanceWarning):
|
|
res = tdi + other
|
|
tm.assert_series_equal(res, expected_add)
|
|
|
|
with tm.assert_produces_warning(PerformanceWarning):
|
|
res2 = other + tdi
|
|
tm.assert_series_equal(res2, expected_add)
|
|
|
|
expected_sub = Series([tdi[n] - other[n] for n in range(len(tdi))],
|
|
name=names[2])
|
|
|
|
with tm.assert_produces_warning(PerformanceWarning):
|
|
res3 = tdi - other
|
|
tm.assert_series_equal(res3, expected_sub)
|
|
|
|
@pytest.mark.parametrize('box', [np.array, pd.Index, pd.Series])
|
|
def test_tdi_add_sub_anchored_offset_arraylike(self, box):
|
|
# GH#18824
|
|
tdi = TimedeltaIndex(['1 days 00:00:00', '3 days 04:00:00'])
|
|
|
|
anchored = box([pd.offsets.MonthEnd(), pd.offsets.Day(n=2)])
|
|
|
|
# addition/subtraction ops with anchored offsets should issue
|
|
# a PerformanceWarning and _then_ raise a TypeError.
|
|
with pytest.raises(TypeError):
|
|
with tm.assert_produces_warning(PerformanceWarning):
|
|
tdi + anchored
|
|
with pytest.raises(TypeError):
|
|
with tm.assert_produces_warning(PerformanceWarning):
|
|
anchored + tdi
|
|
with pytest.raises(TypeError):
|
|
with tm.assert_produces_warning(PerformanceWarning):
|
|
tdi - anchored
|
|
with pytest.raises(TypeError):
|
|
with tm.assert_produces_warning(PerformanceWarning):
|
|
anchored - tdi
|
|
|
|
def test_ufunc_coercions(self):
|
|
# normal ops are also tested in tseries/test_timedeltas.py
|
|
idx = TimedeltaIndex(['2H', '4H', '6H', '8H', '10H'],
|
|
freq='2H', name='x')
|
|
|
|
for result in [idx * 2, np.multiply(idx, 2)]:
|
|
assert isinstance(result, TimedeltaIndex)
|
|
exp = TimedeltaIndex(['4H', '8H', '12H', '16H', '20H'],
|
|
freq='4H', name='x')
|
|
tm.assert_index_equal(result, exp)
|
|
assert result.freq == '4H'
|
|
|
|
for result in [idx / 2, np.divide(idx, 2)]:
|
|
assert isinstance(result, TimedeltaIndex)
|
|
exp = TimedeltaIndex(['1H', '2H', '3H', '4H', '5H'],
|
|
freq='H', name='x')
|
|
tm.assert_index_equal(result, exp)
|
|
assert result.freq == 'H'
|
|
|
|
idx = TimedeltaIndex(['2H', '4H', '6H', '8H', '10H'],
|
|
freq='2H', name='x')
|
|
for result in [-idx, np.negative(idx)]:
|
|
assert isinstance(result, TimedeltaIndex)
|
|
exp = TimedeltaIndex(['-2H', '-4H', '-6H', '-8H', '-10H'],
|
|
freq='-2H', name='x')
|
|
tm.assert_index_equal(result, exp)
|
|
assert result.freq == '-2H'
|
|
|
|
idx = TimedeltaIndex(['-2H', '-1H', '0H', '1H', '2H'],
|
|
freq='H', name='x')
|
|
for result in [abs(idx), np.absolute(idx)]:
|
|
assert isinstance(result, TimedeltaIndex)
|
|
exp = TimedeltaIndex(['2H', '1H', '0H', '1H', '2H'],
|
|
freq=None, name='x')
|
|
tm.assert_index_equal(result, exp)
|
|
assert result.freq is None
|
|
|
|
# -------------------------------------------------------------
|
|
# Binary operations TimedeltaIndex and integer
|
|
|
|
def test_tdi_add_int(self, one):
|
|
# Variants of `one` for #19012
|
|
rng = timedelta_range('1 days 09:00:00', freq='H', periods=10)
|
|
result = rng + one
|
|
expected = timedelta_range('1 days 10:00:00', freq='H', periods=10)
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
def test_tdi_iadd_int(self, one):
|
|
rng = timedelta_range('1 days 09:00:00', freq='H', periods=10)
|
|
expected = timedelta_range('1 days 10:00:00', freq='H', periods=10)
|
|
rng += one
|
|
tm.assert_index_equal(rng, expected)
|
|
|
|
def test_tdi_sub_int(self, one):
|
|
rng = timedelta_range('1 days 09:00:00', freq='H', periods=10)
|
|
result = rng - one
|
|
expected = timedelta_range('1 days 08:00:00', freq='H', periods=10)
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
def test_tdi_isub_int(self, one):
|
|
rng = timedelta_range('1 days 09:00:00', freq='H', periods=10)
|
|
expected = timedelta_range('1 days 08:00:00', freq='H', periods=10)
|
|
rng -= one
|
|
tm.assert_index_equal(rng, expected)
|
|
|
|
# -------------------------------------------------------------
|
|
# Binary operations TimedeltaIndex and timedelta-like
|
|
|
|
def test_tdi_add_timedeltalike(self, delta):
|
|
# only test adding/sub offsets as + is now numeric
|
|
rng = timedelta_range('1 days', '10 days')
|
|
result = rng + delta
|
|
expected = timedelta_range('1 days 02:00:00', '10 days 02:00:00',
|
|
freq='D')
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
def test_tdi_iadd_timedeltalike(self, delta):
|
|
# only test adding/sub offsets as + is now numeric
|
|
rng = timedelta_range('1 days', '10 days')
|
|
expected = timedelta_range('1 days 02:00:00', '10 days 02:00:00',
|
|
freq='D')
|
|
rng += delta
|
|
tm.assert_index_equal(rng, expected)
|
|
|
|
def test_tdi_sub_timedeltalike(self, delta):
|
|
# only test adding/sub offsets as - is now numeric
|
|
rng = timedelta_range('1 days', '10 days')
|
|
result = rng - delta
|
|
expected = timedelta_range('0 days 22:00:00', '9 days 22:00:00')
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
def test_tdi_isub_timedeltalike(self, delta):
|
|
# only test adding/sub offsets as - is now numeric
|
|
rng = timedelta_range('1 days', '10 days')
|
|
expected = timedelta_range('0 days 22:00:00', '9 days 22:00:00')
|
|
rng -= delta
|
|
tm.assert_index_equal(rng, expected)
|
|
|
|
# -------------------------------------------------------------
|
|
# Binary operations TimedeltaIndex and datetime-like
|
|
|
|
def test_tdi_sub_timestamp_raises(self):
|
|
idx = TimedeltaIndex(['1 day', '2 day'])
|
|
msg = "cannot subtract a datelike from a TimedeltaIndex"
|
|
with tm.assert_raises_regex(TypeError, msg):
|
|
idx - Timestamp('2011-01-01')
|
|
|
|
def test_tdi_add_timestamp(self):
|
|
idx = TimedeltaIndex(['1 day', '2 day'])
|
|
|
|
result = idx + Timestamp('2011-01-01')
|
|
expected = DatetimeIndex(['2011-01-02', '2011-01-03'])
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
def test_tdi_radd_timestamp(self):
|
|
idx = TimedeltaIndex(['1 day', '2 day'])
|
|
|
|
result = Timestamp('2011-01-01') + idx
|
|
expected = DatetimeIndex(['2011-01-02', '2011-01-03'])
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
# -------------------------------------------------------------
|
|
# __add__/__sub__ with ndarray[datetime64] and ndarray[timedelta64]
|
|
|
|
def test_tdi_sub_dt64_array(self):
|
|
dti = pd.date_range('2016-01-01', periods=3)
|
|
tdi = dti - dti.shift(1)
|
|
dtarr = dti.values
|
|
|
|
with pytest.raises(TypeError):
|
|
tdi - dtarr
|
|
|
|
# TimedeltaIndex.__rsub__
|
|
expected = pd.DatetimeIndex(dtarr) - tdi
|
|
result = dtarr - tdi
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
def test_tdi_add_dt64_array(self):
|
|
dti = pd.date_range('2016-01-01', periods=3)
|
|
tdi = dti - dti.shift(1)
|
|
dtarr = dti.values
|
|
|
|
expected = pd.DatetimeIndex(dtarr) + tdi
|
|
result = tdi + dtarr
|
|
tm.assert_index_equal(result, expected)
|
|
result = dtarr + tdi
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
def test_tdi_add_td64_array(self):
|
|
dti = pd.date_range('2016-01-01', periods=3)
|
|
tdi = dti - dti.shift(1)
|
|
tdarr = tdi.values
|
|
|
|
expected = 2 * tdi
|
|
result = tdi + tdarr
|
|
tm.assert_index_equal(result, expected)
|
|
result = tdarr + tdi
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
def test_tdi_sub_td64_array(self):
|
|
dti = pd.date_range('2016-01-01', periods=3)
|
|
tdi = dti - dti.shift(1)
|
|
tdarr = tdi.values
|
|
|
|
expected = 0 * tdi
|
|
result = tdi - tdarr
|
|
tm.assert_index_equal(result, expected)
|
|
result = tdarr - tdi
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
# -------------------------------------------------------------
|
|
|
|
def test_subtraction_ops(self):
|
|
# with datetimes/timedelta and tdi/dti
|
|
tdi = TimedeltaIndex(['1 days', pd.NaT, '2 days'], name='foo')
|
|
dti = date_range('20130101', periods=3, name='bar')
|
|
td = Timedelta('1 days')
|
|
dt = Timestamp('20130101')
|
|
|
|
pytest.raises(TypeError, lambda: tdi - dt)
|
|
pytest.raises(TypeError, lambda: tdi - dti)
|
|
pytest.raises(TypeError, lambda: td - dt)
|
|
pytest.raises(TypeError, lambda: td - dti)
|
|
|
|
result = dt - dti
|
|
expected = TimedeltaIndex(['0 days', '-1 days', '-2 days'], name='bar')
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
result = dti - dt
|
|
expected = TimedeltaIndex(['0 days', '1 days', '2 days'], name='bar')
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
result = tdi - td
|
|
expected = TimedeltaIndex(['0 days', pd.NaT, '1 days'], name='foo')
|
|
tm.assert_index_equal(result, expected, check_names=False)
|
|
|
|
result = td - tdi
|
|
expected = TimedeltaIndex(['0 days', pd.NaT, '-1 days'], name='foo')
|
|
tm.assert_index_equal(result, expected, check_names=False)
|
|
|
|
result = dti - td
|
|
expected = DatetimeIndex(
|
|
['20121231', '20130101', '20130102'], name='bar')
|
|
tm.assert_index_equal(result, expected, check_names=False)
|
|
|
|
result = dt - tdi
|
|
expected = DatetimeIndex(['20121231', pd.NaT, '20121230'], name='foo')
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
def test_subtraction_ops_with_tz(self):
|
|
|
|
# check that dt/dti subtraction ops with tz are validated
|
|
dti = date_range('20130101', periods=3)
|
|
ts = Timestamp('20130101')
|
|
dt = ts.to_pydatetime()
|
|
dti_tz = date_range('20130101', periods=3).tz_localize('US/Eastern')
|
|
ts_tz = Timestamp('20130101').tz_localize('US/Eastern')
|
|
ts_tz2 = Timestamp('20130101').tz_localize('CET')
|
|
dt_tz = ts_tz.to_pydatetime()
|
|
td = Timedelta('1 days')
|
|
|
|
def _check(result, expected):
|
|
assert result == expected
|
|
assert isinstance(result, Timedelta)
|
|
|
|
# scalars
|
|
result = ts - ts
|
|
expected = Timedelta('0 days')
|
|
_check(result, expected)
|
|
|
|
result = dt_tz - ts_tz
|
|
expected = Timedelta('0 days')
|
|
_check(result, expected)
|
|
|
|
result = ts_tz - dt_tz
|
|
expected = Timedelta('0 days')
|
|
_check(result, expected)
|
|
|
|
# tz mismatches
|
|
pytest.raises(TypeError, lambda: dt_tz - ts)
|
|
pytest.raises(TypeError, lambda: dt_tz - dt)
|
|
pytest.raises(TypeError, lambda: dt_tz - ts_tz2)
|
|
pytest.raises(TypeError, lambda: dt - dt_tz)
|
|
pytest.raises(TypeError, lambda: ts - dt_tz)
|
|
pytest.raises(TypeError, lambda: ts_tz2 - ts)
|
|
pytest.raises(TypeError, lambda: ts_tz2 - dt)
|
|
pytest.raises(TypeError, lambda: ts_tz - ts_tz2)
|
|
|
|
# with dti
|
|
pytest.raises(TypeError, lambda: dti - ts_tz)
|
|
pytest.raises(TypeError, lambda: dti_tz - ts)
|
|
pytest.raises(TypeError, lambda: dti_tz - ts_tz2)
|
|
|
|
result = dti_tz - dt_tz
|
|
expected = TimedeltaIndex(['0 days', '1 days', '2 days'])
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
result = dt_tz - dti_tz
|
|
expected = TimedeltaIndex(['0 days', '-1 days', '-2 days'])
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
result = dti_tz - ts_tz
|
|
expected = TimedeltaIndex(['0 days', '1 days', '2 days'])
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
result = ts_tz - dti_tz
|
|
expected = TimedeltaIndex(['0 days', '-1 days', '-2 days'])
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
result = td - td
|
|
expected = Timedelta('0 days')
|
|
_check(result, expected)
|
|
|
|
result = dti_tz - td
|
|
expected = DatetimeIndex(
|
|
['20121231', '20130101', '20130102'], tz='US/Eastern')
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
def test_dti_tdi_numeric_ops(self):
|
|
# These are normally union/diff set-like ops
|
|
tdi = TimedeltaIndex(['1 days', pd.NaT, '2 days'], name='foo')
|
|
dti = date_range('20130101', periods=3, name='bar')
|
|
|
|
# TODO(wesm): unused?
|
|
# td = Timedelta('1 days')
|
|
# dt = Timestamp('20130101')
|
|
|
|
result = tdi - tdi
|
|
expected = TimedeltaIndex(['0 days', pd.NaT, '0 days'], name='foo')
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
result = tdi + tdi
|
|
expected = TimedeltaIndex(['2 days', pd.NaT, '4 days'], name='foo')
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
result = dti - tdi # name will be reset
|
|
expected = DatetimeIndex(['20121231', pd.NaT, '20130101'])
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
def test_addition_ops(self):
|
|
# with datetimes/timedelta and tdi/dti
|
|
tdi = TimedeltaIndex(['1 days', pd.NaT, '2 days'], name='foo')
|
|
dti = date_range('20130101', periods=3, name='bar')
|
|
td = Timedelta('1 days')
|
|
dt = Timestamp('20130101')
|
|
|
|
result = tdi + dt
|
|
expected = DatetimeIndex(['20130102', pd.NaT, '20130103'], name='foo')
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
result = dt + tdi
|
|
expected = DatetimeIndex(['20130102', pd.NaT, '20130103'], name='foo')
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
result = td + tdi
|
|
expected = TimedeltaIndex(['2 days', pd.NaT, '3 days'], name='foo')
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
result = tdi + td
|
|
expected = TimedeltaIndex(['2 days', pd.NaT, '3 days'], name='foo')
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
# unequal length
|
|
pytest.raises(ValueError, lambda: tdi + dti[0:1])
|
|
pytest.raises(ValueError, lambda: tdi[0:1] + dti)
|
|
|
|
# random indexes
|
|
pytest.raises(NullFrequencyError, lambda: tdi + Int64Index([1, 2, 3]))
|
|
|
|
# this is a union!
|
|
# pytest.raises(TypeError, lambda : Int64Index([1,2,3]) + tdi)
|
|
|
|
result = tdi + dti # name will be reset
|
|
expected = DatetimeIndex(['20130102', pd.NaT, '20130105'])
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
result = dti + tdi # name will be reset
|
|
expected = DatetimeIndex(['20130102', pd.NaT, '20130105'])
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
result = dt + td
|
|
expected = Timestamp('20130102')
|
|
assert result == expected
|
|
|
|
result = td + dt
|
|
expected = Timestamp('20130102')
|
|
assert result == expected
|
|
|
|
def test_ops_ndarray(self):
|
|
td = Timedelta('1 day')
|
|
|
|
# timedelta, timedelta
|
|
other = pd.to_timedelta(['1 day']).values
|
|
expected = pd.to_timedelta(['2 days']).values
|
|
tm.assert_numpy_array_equal(td + other, expected)
|
|
if LooseVersion(np.__version__) >= LooseVersion('1.8'):
|
|
tm.assert_numpy_array_equal(other + td, expected)
|
|
pytest.raises(TypeError, lambda: td + np.array([1]))
|
|
pytest.raises(TypeError, lambda: np.array([1]) + td)
|
|
|
|
expected = pd.to_timedelta(['0 days']).values
|
|
tm.assert_numpy_array_equal(td - other, expected)
|
|
if LooseVersion(np.__version__) >= LooseVersion('1.8'):
|
|
tm.assert_numpy_array_equal(-other + td, expected)
|
|
pytest.raises(TypeError, lambda: td - np.array([1]))
|
|
pytest.raises(TypeError, lambda: np.array([1]) - td)
|
|
|
|
expected = pd.to_timedelta(['2 days']).values
|
|
tm.assert_numpy_array_equal(td * np.array([2]), expected)
|
|
tm.assert_numpy_array_equal(np.array([2]) * td, expected)
|
|
pytest.raises(TypeError, lambda: td * other)
|
|
pytest.raises(TypeError, lambda: other * td)
|
|
|
|
tm.assert_numpy_array_equal(td / other,
|
|
np.array([1], dtype=np.float64))
|
|
if LooseVersion(np.__version__) >= LooseVersion('1.8'):
|
|
tm.assert_numpy_array_equal(other / td,
|
|
np.array([1], dtype=np.float64))
|
|
|
|
# timedelta, datetime
|
|
other = pd.to_datetime(['2000-01-01']).values
|
|
expected = pd.to_datetime(['2000-01-02']).values
|
|
tm.assert_numpy_array_equal(td + other, expected)
|
|
if LooseVersion(np.__version__) >= LooseVersion('1.8'):
|
|
tm.assert_numpy_array_equal(other + td, expected)
|
|
|
|
expected = pd.to_datetime(['1999-12-31']).values
|
|
tm.assert_numpy_array_equal(-td + other, expected)
|
|
if LooseVersion(np.__version__) >= LooseVersion('1.8'):
|
|
tm.assert_numpy_array_equal(other - td, expected)
|
|
|
|
def test_ops_series(self):
|
|
# regression test for GH8813
|
|
td = Timedelta('1 day')
|
|
other = pd.Series([1, 2])
|
|
expected = pd.Series(pd.to_timedelta(['1 day', '2 days']))
|
|
tm.assert_series_equal(expected, td * other)
|
|
tm.assert_series_equal(expected, other * td)
|
|
|
|
def test_ops_series_object(self):
|
|
# GH 13043
|
|
s = pd.Series([pd.Timestamp('2015-01-01', tz='US/Eastern'),
|
|
pd.Timestamp('2015-01-01', tz='Asia/Tokyo')],
|
|
name='xxx')
|
|
assert s.dtype == object
|
|
|
|
exp = pd.Series([pd.Timestamp('2015-01-02', tz='US/Eastern'),
|
|
pd.Timestamp('2015-01-02', tz='Asia/Tokyo')],
|
|
name='xxx')
|
|
tm.assert_series_equal(s + pd.Timedelta('1 days'), exp)
|
|
tm.assert_series_equal(pd.Timedelta('1 days') + s, exp)
|
|
|
|
# object series & object series
|
|
s2 = pd.Series([pd.Timestamp('2015-01-03', tz='US/Eastern'),
|
|
pd.Timestamp('2015-01-05', tz='Asia/Tokyo')],
|
|
name='xxx')
|
|
assert s2.dtype == object
|
|
exp = pd.Series([pd.Timedelta('2 days'), pd.Timedelta('4 days')],
|
|
name='xxx')
|
|
tm.assert_series_equal(s2 - s, exp)
|
|
tm.assert_series_equal(s - s2, -exp)
|
|
|
|
s = pd.Series([pd.Timedelta('01:00:00'), pd.Timedelta('02:00:00')],
|
|
name='xxx', dtype=object)
|
|
assert s.dtype == object
|
|
|
|
exp = pd.Series([pd.Timedelta('01:30:00'), pd.Timedelta('02:30:00')],
|
|
name='xxx')
|
|
tm.assert_series_equal(s + pd.Timedelta('00:30:00'), exp)
|
|
tm.assert_series_equal(pd.Timedelta('00:30:00') + s, exp)
|
|
|
|
def test_timedelta_ops_with_missing_values(self):
|
|
# setup
|
|
s1 = pd.to_timedelta(Series(['00:00:01']))
|
|
s2 = pd.to_timedelta(Series(['00:00:02']))
|
|
sn = pd.to_timedelta(Series([pd.NaT]))
|
|
df1 = pd.DataFrame(['00:00:01']).apply(pd.to_timedelta)
|
|
df2 = pd.DataFrame(['00:00:02']).apply(pd.to_timedelta)
|
|
dfn = pd.DataFrame([pd.NaT]).apply(pd.to_timedelta)
|
|
scalar1 = pd.to_timedelta('00:00:01')
|
|
scalar2 = pd.to_timedelta('00:00:02')
|
|
timedelta_NaT = pd.to_timedelta('NaT')
|
|
NA = np.nan
|
|
|
|
actual = scalar1 + scalar1
|
|
assert actual == scalar2
|
|
actual = scalar2 - scalar1
|
|
assert actual == scalar1
|
|
|
|
actual = s1 + s1
|
|
tm.assert_series_equal(actual, s2)
|
|
actual = s2 - s1
|
|
tm.assert_series_equal(actual, s1)
|
|
|
|
actual = s1 + scalar1
|
|
tm.assert_series_equal(actual, s2)
|
|
actual = scalar1 + s1
|
|
tm.assert_series_equal(actual, s2)
|
|
actual = s2 - scalar1
|
|
tm.assert_series_equal(actual, s1)
|
|
actual = -scalar1 + s2
|
|
tm.assert_series_equal(actual, s1)
|
|
|
|
actual = s1 + timedelta_NaT
|
|
tm.assert_series_equal(actual, sn)
|
|
actual = timedelta_NaT + s1
|
|
tm.assert_series_equal(actual, sn)
|
|
actual = s1 - timedelta_NaT
|
|
tm.assert_series_equal(actual, sn)
|
|
actual = -timedelta_NaT + s1
|
|
tm.assert_series_equal(actual, sn)
|
|
|
|
with pytest.raises(TypeError):
|
|
s1 + np.nan
|
|
with pytest.raises(TypeError):
|
|
np.nan + s1
|
|
with pytest.raises(TypeError):
|
|
s1 - np.nan
|
|
with pytest.raises(TypeError):
|
|
-np.nan + s1
|
|
|
|
actual = s1 + pd.NaT
|
|
tm.assert_series_equal(actual, sn)
|
|
actual = s2 - pd.NaT
|
|
tm.assert_series_equal(actual, sn)
|
|
|
|
actual = s1 + df1
|
|
tm.assert_frame_equal(actual, df2)
|
|
actual = s2 - df1
|
|
tm.assert_frame_equal(actual, df1)
|
|
actual = df1 + s1
|
|
tm.assert_frame_equal(actual, df2)
|
|
actual = df2 - s1
|
|
tm.assert_frame_equal(actual, df1)
|
|
|
|
actual = df1 + df1
|
|
tm.assert_frame_equal(actual, df2)
|
|
actual = df2 - df1
|
|
tm.assert_frame_equal(actual, df1)
|
|
|
|
actual = df1 + scalar1
|
|
tm.assert_frame_equal(actual, df2)
|
|
actual = df2 - scalar1
|
|
tm.assert_frame_equal(actual, df1)
|
|
|
|
actual = df1 + timedelta_NaT
|
|
tm.assert_frame_equal(actual, dfn)
|
|
actual = df1 - timedelta_NaT
|
|
tm.assert_frame_equal(actual, dfn)
|
|
|
|
actual = df1 + NA
|
|
tm.assert_frame_equal(actual, dfn)
|
|
actual = df1 - NA
|
|
tm.assert_frame_equal(actual, dfn)
|
|
|
|
actual = df1 + pd.NaT # NaT is datetime, not timedelta
|
|
tm.assert_frame_equal(actual, dfn)
|
|
actual = df1 - pd.NaT
|
|
tm.assert_frame_equal(actual, dfn)
|
|
|
|
def test_add_overflow(self):
|
|
# see gh-14068
|
|
msg = "too (big|large) to convert"
|
|
with tm.assert_raises_regex(OverflowError, msg):
|
|
to_timedelta(106580, 'D') + Timestamp('2000')
|
|
with tm.assert_raises_regex(OverflowError, msg):
|
|
Timestamp('2000') + to_timedelta(106580, 'D')
|
|
|
|
_NaT = int(pd.NaT) + 1
|
|
msg = "Overflow in int64 addition"
|
|
with tm.assert_raises_regex(OverflowError, msg):
|
|
to_timedelta([106580], 'D') + Timestamp('2000')
|
|
with tm.assert_raises_regex(OverflowError, msg):
|
|
Timestamp('2000') + to_timedelta([106580], 'D')
|
|
with tm.assert_raises_regex(OverflowError, msg):
|
|
to_timedelta([_NaT]) - Timedelta('1 days')
|
|
with tm.assert_raises_regex(OverflowError, msg):
|
|
to_timedelta(['5 days', _NaT]) - Timedelta('1 days')
|
|
with tm.assert_raises_regex(OverflowError, msg):
|
|
(to_timedelta([_NaT, '5 days', '1 hours']) -
|
|
to_timedelta(['7 seconds', _NaT, '4 hours']))
|
|
|
|
# These should not overflow!
|
|
exp = TimedeltaIndex([pd.NaT])
|
|
result = to_timedelta([pd.NaT]) - Timedelta('1 days')
|
|
tm.assert_index_equal(result, exp)
|
|
|
|
exp = TimedeltaIndex(['4 days', pd.NaT])
|
|
result = to_timedelta(['5 days', pd.NaT]) - Timedelta('1 days')
|
|
tm.assert_index_equal(result, exp)
|
|
|
|
exp = TimedeltaIndex([pd.NaT, pd.NaT, '5 hours'])
|
|
result = (to_timedelta([pd.NaT, '5 days', '1 hours']) +
|
|
to_timedelta(['7 seconds', pd.NaT, '4 hours']))
|
|
tm.assert_index_equal(result, exp)
|
|
|
|
def test_timedeltaindex_add_timestamp_nat_masking(self):
|
|
# GH17991 checking for overflow-masking with NaT
|
|
tdinat = pd.to_timedelta(['24658 days 11:15:00', 'NaT'])
|
|
|
|
tsneg = Timestamp('1950-01-01')
|
|
ts_neg_variants = [tsneg,
|
|
tsneg.to_pydatetime(),
|
|
tsneg.to_datetime64().astype('datetime64[ns]'),
|
|
tsneg.to_datetime64().astype('datetime64[D]')]
|
|
|
|
tspos = Timestamp('1980-01-01')
|
|
ts_pos_variants = [tspos,
|
|
tspos.to_pydatetime(),
|
|
tspos.to_datetime64().astype('datetime64[ns]'),
|
|
tspos.to_datetime64().astype('datetime64[D]')]
|
|
|
|
for variant in ts_neg_variants + ts_pos_variants:
|
|
res = tdinat + variant
|
|
assert res[1] is pd.NaT
|
|
|
|
def test_tdi_ops_attributes(self):
|
|
rng = timedelta_range('2 days', periods=5, freq='2D', name='x')
|
|
|
|
result = rng + 1
|
|
exp = timedelta_range('4 days', periods=5, freq='2D', name='x')
|
|
tm.assert_index_equal(result, exp)
|
|
assert result.freq == '2D'
|
|
|
|
result = rng - 2
|
|
exp = timedelta_range('-2 days', periods=5, freq='2D', name='x')
|
|
tm.assert_index_equal(result, exp)
|
|
assert result.freq == '2D'
|
|
|
|
result = rng * 2
|
|
exp = timedelta_range('4 days', periods=5, freq='4D', name='x')
|
|
tm.assert_index_equal(result, exp)
|
|
assert result.freq == '4D'
|
|
|
|
result = rng / 2
|
|
exp = timedelta_range('1 days', periods=5, freq='D', name='x')
|
|
tm.assert_index_equal(result, exp)
|
|
assert result.freq == 'D'
|
|
|
|
result = -rng
|
|
exp = timedelta_range('-2 days', periods=5, freq='-2D', name='x')
|
|
tm.assert_index_equal(result, exp)
|
|
assert result.freq == '-2D'
|
|
|
|
rng = pd.timedelta_range('-2 days', periods=5, freq='D', name='x')
|
|
|
|
result = abs(rng)
|
|
exp = TimedeltaIndex(['2 days', '1 days', '0 days', '1 days',
|
|
'2 days'], name='x')
|
|
tm.assert_index_equal(result, exp)
|
|
assert result.freq is None
|
|
|
|
# TODO: Needs more informative name, probably split up into
|
|
# more targeted tests
|
|
def test_timedelta(self, freq):
|
|
index = date_range('1/1/2000', periods=50, freq=freq)
|
|
|
|
shifted = index + timedelta(1)
|
|
back = shifted + timedelta(-1)
|
|
tm.assert_index_equal(index, back)
|
|
|
|
if freq == 'D':
|
|
expected = pd.tseries.offsets.Day(1)
|
|
assert index.freq == expected
|
|
assert shifted.freq == expected
|
|
assert back.freq == expected
|
|
else: # freq == 'B'
|
|
assert index.freq == pd.tseries.offsets.BusinessDay(1)
|
|
assert shifted.freq is None
|
|
assert back.freq == pd.tseries.offsets.BusinessDay(1)
|
|
|
|
result = index - timedelta(1)
|
|
expected = index + timedelta(-1)
|
|
tm.assert_index_equal(result, expected)
|
|
|
|
# GH4134, buggy with timedeltas
|
|
rng = date_range('2013', '2014')
|
|
s = Series(rng)
|
|
result1 = rng - pd.offsets.Hour(1)
|
|
result2 = DatetimeIndex(s - np.timedelta64(100000000))
|
|
result3 = rng - np.timedelta64(100000000)
|
|
result4 = DatetimeIndex(s - pd.offsets.Hour(1))
|
|
tm.assert_index_equal(result1, result4)
|
|
tm.assert_index_equal(result2, result3)
|