Skip to content

[POC] implement test_arithmetic.py #22033

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 4 commits into from
Jul 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 1 addition & 37 deletions pandas/tests/indexes/test_numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import pandas.util.testing as tm

import pandas as pd
from pandas._libs.tslibs import Timestamp, Timedelta
from pandas._libs.tslibs import Timestamp

from pandas.tests.indexes.common import Base

Expand All @@ -26,42 +26,6 @@ def full_like(array, value):
return ret


class TestIndexArithmeticWithTimedeltaScalar(object):

@pytest.mark.parametrize('index', [
Int64Index(range(1, 11)),
UInt64Index(range(1, 11)),
Float64Index(range(1, 11)),
RangeIndex(1, 11)])
@pytest.mark.parametrize('scalar_td', [Timedelta(days=1),
Timedelta(days=1).to_timedelta64(),
Timedelta(days=1).to_pytimedelta()])
def test_index_mul_timedelta(self, scalar_td, index):
# GH#19333
expected = pd.timedelta_range('1 days', '10 days')

result = index * scalar_td
tm.assert_index_equal(result, expected)
commute = scalar_td * index
tm.assert_index_equal(commute, expected)

@pytest.mark.parametrize('index', [Int64Index(range(1, 3)),
UInt64Index(range(1, 3)),
Float64Index(range(1, 3)),
RangeIndex(1, 3)])
@pytest.mark.parametrize('scalar_td', [Timedelta(days=1),
Timedelta(days=1).to_timedelta64(),
Timedelta(days=1).to_pytimedelta()])
def test_index_rdiv_timedelta(self, scalar_td, index):
expected = pd.TimedeltaIndex(['1 Day', '12 Hours'])

result = scalar_td / index
tm.assert_index_equal(result, expected)

with pytest.raises(TypeError):
index / scalar_td


class Numeric(Base):

def test_can_hold_identifiers(self):
Expand Down
19 changes: 0 additions & 19 deletions pandas/tests/series/test_arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -891,22 +891,3 @@ def test_td64series_mul_timedeltalike_invalid(self, scalar_td):
td1 * scalar_td
with tm.assert_raises_regex(TypeError, pattern):
scalar_td * td1


class TestTimedeltaSeriesInvalidArithmeticOps(object):
@pytest.mark.parametrize('scalar_td', [
timedelta(minutes=5, seconds=4),
Timedelta('5m4s'),
Timedelta('5m4s').to_timedelta64()])
def test_td64series_pow_invalid(self, scalar_td):
td1 = Series([timedelta(minutes=5, seconds=3)] * 3)
td1.iloc[2] = np.nan

# check that we are getting a TypeError
# with 'operate' (from core/ops.py) for the ops that are not
# defined
pattern = 'operate|unsupported|cannot|not supported'
with tm.assert_raises_regex(TypeError, pattern):
scalar_td ** td1
with tm.assert_raises_regex(TypeError, pattern):
td1 ** scalar_td
119 changes: 119 additions & 0 deletions pandas/tests/test_arithmetic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# -*- coding: utf-8 -*-
# Arithmetc tests for DataFrame/Series/Index/Array classes that should
# behave identically.
from datetime import timedelta

import pytest
import numpy as np

import pandas as pd
import pandas.util.testing as tm

from pandas import Timedelta


# ------------------------------------------------------------------
# Numeric dtypes Arithmetic with Timedelta Scalar

class TestNumericArraylikeArithmeticWithTimedeltaScalar(object):

@pytest.mark.parametrize('box', [
pd.Index,
pd.Series,
pytest.param(pd.DataFrame,
marks=pytest.mark.xfail(reason="block.eval incorrect",
strict=True))
])
@pytest.mark.parametrize('index', [
pd.Int64Index(range(1, 11)),
pd.UInt64Index(range(1, 11)),
pd.Float64Index(range(1, 11)),
pd.RangeIndex(1, 11)],
ids=lambda x: type(x).__name__)
@pytest.mark.parametrize('scalar_td', [
Timedelta(days=1),
Timedelta(days=1).to_timedelta64(),
Timedelta(days=1).to_pytimedelta()],
ids=lambda x: type(x).__name__)
def test_index_mul_timedelta(self, scalar_td, index, box):
# GH#19333

if (box is pd.Series and
type(scalar_td) is timedelta and index.dtype == 'f8'):
raise pytest.xfail(reason="Cannot multiply timedelta by float")

expected = pd.timedelta_range('1 days', '10 days')

index = tm.box_expected(index, box)
expected = tm.box_expected(expected, box)

result = index * scalar_td
tm.assert_equal(result, expected)

commute = scalar_td * index
tm.assert_equal(commute, expected)

@pytest.mark.parametrize('box', [pd.Index, pd.Series, pd.DataFrame])
@pytest.mark.parametrize('index', [
pd.Int64Index(range(1, 3)),
pd.UInt64Index(range(1, 3)),
pd.Float64Index(range(1, 3)),
pd.RangeIndex(1, 3)],
ids=lambda x: type(x).__name__)
@pytest.mark.parametrize('scalar_td', [
Timedelta(days=1),
Timedelta(days=1).to_timedelta64(),
Timedelta(days=1).to_pytimedelta()],
ids=lambda x: type(x).__name__)
def test_index_rdiv_timedelta(self, scalar_td, index, box):

if box is pd.Series and type(scalar_td) is timedelta:
raise pytest.xfail(reason="TODO: Figure out why this case fails")
if box is pd.DataFrame and isinstance(scalar_td, timedelta):
raise pytest.xfail(reason="TODO: Figure out why this case fails")

expected = pd.TimedeltaIndex(['1 Day', '12 Hours'])

index = tm.box_expected(index, box)
expected = tm.box_expected(expected, box)

result = scalar_td / index
tm.assert_equal(result, expected)

with pytest.raises(TypeError):
index / scalar_td


# ------------------------------------------------------------------
# Timedelta64[ns] dtype Arithmetic Operations


class TestTimedeltaArraylikeInvalidArithmeticOps(object):

@pytest.mark.parametrize('box', [
pd.Index,
pd.Series,
pytest.param(pd.DataFrame,
marks=pytest.mark.xfail(reason="raises ValueError "
"instead of TypeError",
strict=True))
])
@pytest.mark.parametrize('scalar_td', [
timedelta(minutes=5, seconds=4),
Timedelta('5m4s'),
Timedelta('5m4s').to_timedelta64()])
def test_td64series_pow_invalid(self, scalar_td, box):
td1 = pd.Series([timedelta(minutes=5, seconds=3)] * 3)
td1.iloc[2] = np.nan

td1 = tm.box_expected(td1, box)

# check that we are getting a TypeError
# with 'operate' (from core/ops.py) for the ops that are not
# defined
pattern = 'operate|unsupported|cannot|not supported'
with tm.assert_raises_regex(TypeError, pattern):
scalar_td ** td1

with tm.assert_raises_regex(TypeError, pattern):
td1 ** scalar_td
44 changes: 44 additions & 0 deletions pandas/util/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1478,6 +1478,50 @@ def assert_panel_equal(left, right,
assert item in left, msg


def assert_equal(left, right, **kwargs):
"""
Wrapper for tm.assert_*_equal to dispatch to the appropriate test function.
Parameters
----------
left : Index, Series, or DataFrame
right : Index, Series, or DataFrame
**kwargs
"""
if isinstance(left, pd.Index):
assert_index_equal(left, right, **kwargs)
elif isinstance(left, pd.Series):
assert_series_equal(left, right, **kwargs)
elif isinstance(left, pd.DataFrame):
assert_frame_equal(left, right, **kwargs)
else:
raise NotImplementedError(type(left))


def box_expected(expected, box_cls):
"""
Helper function to wrap the expected output of a test in a given box_class.
Parameters
----------
expected : np.ndarray, Index, Series
box_cls : {Index, Series, DataFrame}
Returns
-------
subclass of box_cls
"""
if box_cls is pd.Index:
expected = pd.Index(expected)
elif box_cls is pd.Series:
expected = pd.Series(expected)
elif box_cls is pd.DataFrame:
expected = pd.Series(expected).to_frame()
else:
raise NotImplementedError(box_cls)
return expected


# -----------------------------------------------------------------------------
# Sparse

Expand Down