Skip to content

Commit 27a5039

Browse files
jbrockmendeljreback
authored andcommitted
Parametrize tests for Series[timedelta64] integer arithmetic (pandas-dev#19166)
1 parent 499802c commit 27a5039

File tree

1 file changed

+159
-59
lines changed

1 file changed

+159
-59
lines changed

pandas/tests/series/test_operators.py

+159-59
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828
from .common import TestData
2929

3030

31+
@pytest.fixture
32+
def tdser():
33+
return Series(['59 Days', '59 Days', 'NaT'], dtype='timedelta64[ns]')
34+
35+
3136
class TestSeriesComparisons(object):
3237
def test_series_comparison_scalars(self):
3338
series = Series(date_range('1/1/2000', periods=10))
@@ -667,83 +672,178 @@ def test_div(self):
667672
assert_series_equal(result, expected)
668673

669674

670-
class TestTimedeltaSeriesArithmetic(object):
671-
def test_timedelta_series_ops(self):
672-
# GH11925
673-
s = Series(timedelta_range('1 day', periods=3))
674-
ts = Timestamp('2012-01-01')
675-
expected = Series(date_range('2012-01-02', periods=3))
676-
assert_series_equal(ts + s, expected)
677-
assert_series_equal(s + ts, expected)
675+
class TestTimedeltaSeriesArithmeticWithIntegers(object):
676+
# Tests for Series with dtype 'timedelta64[ns]' arithmetic operations
677+
# with integer and int-like others
678678

679-
expected2 = Series(date_range('2011-12-31', periods=3, freq='-1D'))
680-
assert_series_equal(ts - s, expected2)
681-
assert_series_equal(ts + (-s), expected2)
679+
# ------------------------------------------------------------------
680+
# Addition and Subtraction
681+
682+
def test_td64series_add_int_series_invalid(self, tdser):
683+
with pytest.raises(TypeError):
684+
tdser + Series([2, 3, 4])
685+
686+
@pytest.mark.xfail(reason='GH#19123 integer interpreted as nanoseconds')
687+
def test_td64series_radd_int_series_invalid(self, tdser):
688+
with pytest.raises(TypeError):
689+
Series([2, 3, 4]) + tdser
690+
691+
def test_td64series_sub_int_series_invalid(self, tdser):
692+
with pytest.raises(TypeError):
693+
tdser - Series([2, 3, 4])
694+
695+
@pytest.mark.xfail(reason='GH#19123 integer interpreted as nanoseconds')
696+
def test_td64series_rsub_int_series_invalid(self, tdser):
697+
with pytest.raises(TypeError):
698+
Series([2, 3, 4]) - tdser
682699

683-
def test_timedelta64_operations_with_integers(self):
700+
@pytest.mark.parametrize('scalar', [1, 1.5, np.array(2)])
701+
def test_td64series_add_sub_numeric_scalar_invalid(self, scalar, tdser):
702+
with pytest.raises(TypeError):
703+
tdser + scalar
704+
with pytest.raises(TypeError):
705+
scalar + tdser
706+
with pytest.raises(TypeError):
707+
tdser - scalar
708+
with pytest.raises(TypeError):
709+
scalar - tdser
710+
711+
@pytest.mark.parametrize('dtype', ['int64', 'int32', 'int16',
712+
'uint64', 'uint32', 'uint16', 'uint8',
713+
'float64', 'float32', 'float16'])
714+
@pytest.mark.parametrize('vector', [
715+
np.array([1, 2, 3]),
716+
pd.Index([1, 2, 3]),
717+
pytest.param(Series([1, 2, 3]),
718+
marks=pytest.mark.xfail(reason='GH#19123 integer '
719+
'interpreted as nanos'))
720+
])
721+
def test_td64series_add_sub_numeric_array_invalid(self, vector,
722+
dtype, tdser):
723+
vector = vector.astype(dtype)
724+
with pytest.raises(TypeError):
725+
tdser + vector
726+
with pytest.raises(TypeError):
727+
vector + tdser
728+
with pytest.raises(TypeError):
729+
tdser - vector
730+
with pytest.raises(TypeError):
731+
vector - tdser
732+
733+
# ------------------------------------------------------------------
734+
# Multiplicaton and Division
735+
736+
@pytest.mark.parametrize('dtype', ['int64', 'int32', 'int16',
737+
'uint64', 'uint32', 'uint16', 'uint8',
738+
'float64', 'float32', 'float16'])
739+
@pytest.mark.parametrize('vector', [np.array([20, 30, 40]),
740+
pd.Index([20, 30, 40]),
741+
Series([20, 30, 40])])
742+
def test_td64series_div_numeric_array(self, vector, dtype, tdser):
684743
# GH 4521
685744
# divide/multiply by integers
686-
startdate = Series(date_range('2013-01-01', '2013-01-03'))
687-
enddate = Series(date_range('2013-03-01', '2013-03-03'))
745+
vector = vector.astype(dtype)
746+
expected = Series(['2.95D', '1D 23H 12m', 'NaT'],
747+
dtype='timedelta64[ns]')
688748

689-
s1 = enddate - startdate
690-
s1[2] = np.nan
691-
s2 = Series([2, 3, 4])
692-
expected = Series(s1.values.astype(np.int64) / s2, dtype='m8[ns]')
693-
expected[2] = np.nan
694-
result = s1 / s2
749+
result = tdser / vector
695750
assert_series_equal(result, expected)
696751

697-
s2 = Series([20, 30, 40])
698-
expected = Series(s1.values.astype(np.int64) / s2, dtype='m8[ns]')
699-
expected[2] = np.nan
700-
result = s1 / s2
752+
with pytest.raises(TypeError):
753+
vector / tdser
754+
755+
@pytest.mark.parametrize('dtype', ['int64', 'int32', 'int16',
756+
'uint64', 'uint32', 'uint16', 'uint8',
757+
'float64', 'float32', 'float16'])
758+
@pytest.mark.parametrize('vector', [np.array([20, 30, 40]),
759+
pd.Index([20, 30, 40]),
760+
Series([20, 30, 40])])
761+
def test_td64series_mul_numeric_array(self, vector, dtype, tdser):
762+
# GH 4521
763+
# divide/multiply by integers
764+
vector = vector.astype(dtype)
765+
766+
expected = Series(['1180 Days', '1770 Days', 'NaT'],
767+
dtype='timedelta64[ns]')
768+
769+
result = tdser * vector
701770
assert_series_equal(result, expected)
702771

703-
result = s1 / 2
704-
expected = Series(s1.values.astype(np.int64) / 2, dtype='m8[ns]')
705-
expected[2] = np.nan
772+
@pytest.mark.parametrize('dtype', ['int64', 'int32', 'int16',
773+
'uint64', 'uint32', 'uint16', 'uint8',
774+
'float64', 'float32', 'float16'])
775+
@pytest.mark.parametrize('vector', [
776+
np.array([20, 30, 40]),
777+
pytest.param(pd.Index([20, 30, 40]),
778+
marks=pytest.mark.xfail(reason='__mul__ raises '
779+
'instead of returning '
780+
'NotImplemented')),
781+
Series([20, 30, 40])
782+
])
783+
def test_td64series_rmul_numeric_array(self, vector, dtype, tdser):
784+
# GH 4521
785+
# divide/multiply by integers
786+
vector = vector.astype(dtype)
787+
788+
expected = Series(['1180 Days', '1770 Days', 'NaT'],
789+
dtype='timedelta64[ns]')
790+
791+
result = vector * tdser
706792
assert_series_equal(result, expected)
707793

708-
s2 = Series([20, 30, 40])
709-
expected = Series(s1.values.astype(np.int64) * s2, dtype='m8[ns]')
710-
expected[2] = np.nan
711-
result = s1 * s2
794+
@pytest.mark.parametrize('one', [1, np.array(1), 1.0, np.array(1.0)])
795+
def test_td64series_mul_numeric_scalar(self, one, tdser):
796+
# GH 4521
797+
# divide/multiply by integers
798+
expected = Series(['-59 Days', '-59 Days', 'NaT'],
799+
dtype='timedelta64[ns]')
800+
801+
result = tdser * (-one)
802+
assert_series_equal(result, expected)
803+
result = (-one) * tdser
712804
assert_series_equal(result, expected)
713805

714-
for dtype in ['int32', 'int16', 'uint32', 'uint64', 'uint32', 'uint16',
715-
'uint8']:
716-
s2 = Series([20, 30, 40], dtype=dtype)
717-
expected = Series(
718-
s1.values.astype(np.int64) * s2.astype(np.int64),
719-
dtype='m8[ns]')
720-
expected[2] = np.nan
721-
result = s1 * s2
722-
assert_series_equal(result, expected)
806+
expected = Series(['118 Days', '118 Days', 'NaT'],
807+
dtype='timedelta64[ns]')
723808

724-
result = s1 * 2
725-
expected = Series(s1.values.astype(np.int64) * 2, dtype='m8[ns]')
726-
expected[2] = np.nan
809+
result = tdser * (2 * one)
727810
assert_series_equal(result, expected)
811+
result = (2 * one) * tdser
812+
assert_series_equal(result, expected)
813+
814+
@pytest.mark.parametrize('two', [
815+
2, 2.0,
816+
pytest.param(np.array(2),
817+
marks=pytest.mark.xfail(reason='GH#19011 is_list_like '
818+
'incorrectly True.')),
819+
pytest.param(np.array(2.0),
820+
marks=pytest.mark.xfail(reason='GH#19011 is_list_like '
821+
'incorrectly True.')),
822+
])
823+
def test_td64series_div_numeric_scalar(self, two, tdser):
824+
# GH 4521
825+
# divide/multiply by integers
826+
expected = Series(['29.5D', '29.5D', 'NaT'], dtype='timedelta64[ns]')
728827

729-
result = s1 * -1
730-
expected = Series(s1.values.astype(np.int64) * -1, dtype='m8[ns]')
731-
expected[2] = np.nan
828+
result = tdser / two
732829
assert_series_equal(result, expected)
733830

734-
# invalid ops
735-
assert_series_equal(s1 / s2.astype(float),
736-
Series([Timedelta('2 days 22:48:00'), Timedelta(
737-
'1 days 23:12:00'), Timedelta('NaT')]))
738-
assert_series_equal(s1 / 2.0,
739-
Series([Timedelta('29 days 12:00:00'), Timedelta(
740-
'29 days 12:00:00'), Timedelta('NaT')]))
741-
742-
for op in ['__add__', '__sub__']:
743-
sop = getattr(s1, op, None)
744-
if sop is not None:
745-
pytest.raises(TypeError, sop, 1)
746-
pytest.raises(TypeError, sop, s2.values)
831+
832+
class TestTimedeltaSeriesArithmetic(object):
833+
def test_td64series_add_sub_timestamp(self):
834+
# GH11925
835+
tdser = Series(timedelta_range('1 day', periods=3))
836+
ts = Timestamp('2012-01-01')
837+
expected = Series(date_range('2012-01-02', periods=3))
838+
assert_series_equal(ts + tdser, expected)
839+
assert_series_equal(tdser + ts, expected)
840+
841+
expected2 = Series(date_range('2011-12-31', periods=3, freq='-1D'))
842+
assert_series_equal(ts - tdser, expected2)
843+
assert_series_equal(ts + (-tdser), expected2)
844+
845+
with pytest.raises(TypeError):
846+
tdser - ts
747847

748848
def test_timedelta64_operations_with_DateOffset(self):
749849
# GH 10699

0 commit comments

Comments
 (0)