8th day of python challenges 111-117
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
import pandas as pd
|
||||
from pandas import (
|
||||
Index,
|
||||
Interval,
|
||||
IntervalIndex,
|
||||
Timedelta,
|
||||
Timestamp,
|
||||
date_range,
|
||||
timedelta_range,
|
||||
)
|
||||
from pandas.core.arrays import IntervalArray
|
||||
import pandas.util.testing as tm
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
params=[
|
||||
(Index([0, 2, 4]), Index([1, 3, 5])),
|
||||
(Index([0.0, 1.0, 2.0]), Index([1.0, 2.0, 3.0])),
|
||||
(timedelta_range("0 days", periods=3), timedelta_range("1 day", periods=3)),
|
||||
(date_range("20170101", periods=3), date_range("20170102", periods=3)),
|
||||
(
|
||||
date_range("20170101", periods=3, tz="US/Eastern"),
|
||||
date_range("20170102", periods=3, tz="US/Eastern"),
|
||||
),
|
||||
],
|
||||
ids=lambda x: str(x[0].dtype),
|
||||
)
|
||||
def left_right_dtypes(request):
|
||||
"""
|
||||
Fixture for building an IntervalArray from various dtypes
|
||||
"""
|
||||
return request.param
|
||||
|
||||
|
||||
class TestAttributes:
|
||||
@pytest.mark.parametrize(
|
||||
"left, right",
|
||||
[
|
||||
(0, 1),
|
||||
(Timedelta("0 days"), Timedelta("1 day")),
|
||||
(Timestamp("2018-01-01"), Timestamp("2018-01-02")),
|
||||
pytest.param(
|
||||
Timestamp("2018-01-01", tz="US/Eastern"),
|
||||
Timestamp("2018-01-02", tz="US/Eastern"),
|
||||
marks=pytest.mark.xfail(strict=True, reason="GH 27011"),
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("constructor", [IntervalArray, IntervalIndex])
|
||||
def test_is_empty(self, constructor, left, right, closed):
|
||||
# GH27219
|
||||
tuples = [(left, left), (left, right), np.nan]
|
||||
expected = np.array([closed != "both", False, False])
|
||||
result = constructor.from_tuples(tuples, closed=closed).is_empty
|
||||
tm.assert_numpy_array_equal(result, expected)
|
||||
|
||||
|
||||
class TestMethods:
|
||||
@pytest.mark.parametrize("new_closed", ["left", "right", "both", "neither"])
|
||||
def test_set_closed(self, closed, new_closed):
|
||||
# GH 21670
|
||||
array = IntervalArray.from_breaks(range(10), closed=closed)
|
||||
result = array.set_closed(new_closed)
|
||||
expected = IntervalArray.from_breaks(range(10), closed=new_closed)
|
||||
tm.assert_extension_array_equal(result, expected)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"other",
|
||||
[
|
||||
Interval(0, 1, closed="right"),
|
||||
IntervalArray.from_breaks([1, 2, 3, 4], closed="right"),
|
||||
],
|
||||
)
|
||||
def test_where_raises(self, other):
|
||||
ser = pd.Series(IntervalArray.from_breaks([1, 2, 3, 4], closed="left"))
|
||||
match = "'value.closed' is 'right', expected 'left'."
|
||||
with pytest.raises(ValueError, match=match):
|
||||
ser.where([True, False, True], other=other)
|
||||
|
||||
|
||||
class TestSetitem:
|
||||
def test_set_na(self, left_right_dtypes):
|
||||
left, right = left_right_dtypes
|
||||
result = IntervalArray.from_arrays(left, right)
|
||||
result[0] = np.nan
|
||||
|
||||
expected_left = Index([left._na_value] + list(left[1:]))
|
||||
expected_right = Index([right._na_value] + list(right[1:]))
|
||||
expected = IntervalArray.from_arrays(expected_left, expected_right)
|
||||
|
||||
tm.assert_extension_array_equal(result, expected)
|
||||
|
||||
|
||||
def test_repr_matches():
|
||||
idx = IntervalIndex.from_breaks([1, 2, 3])
|
||||
a = repr(idx)
|
||||
b = repr(idx.values)
|
||||
assert a.replace("Index", "Array") == b
|
@@ -0,0 +1,90 @@
|
||||
"""Tests for Interval-Interval operations, such as overlaps, contains, etc."""
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from pandas import Interval, IntervalIndex, Timedelta, Timestamp
|
||||
from pandas.core.arrays import IntervalArray
|
||||
import pandas.util.testing as tm
|
||||
|
||||
|
||||
@pytest.fixture(params=[IntervalArray, IntervalIndex])
|
||||
def constructor(request):
|
||||
"""
|
||||
Fixture for testing both interval container classes.
|
||||
"""
|
||||
return request.param
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
params=[
|
||||
(Timedelta("0 days"), Timedelta("1 day")),
|
||||
(Timestamp("2018-01-01"), Timedelta("1 day")),
|
||||
(0, 1),
|
||||
],
|
||||
ids=lambda x: type(x[0]).__name__,
|
||||
)
|
||||
def start_shift(request):
|
||||
"""
|
||||
Fixture for generating intervals of different types from a start value
|
||||
and a shift value that can be added to start to generate an endpoint.
|
||||
"""
|
||||
return request.param
|
||||
|
||||
|
||||
class TestOverlaps:
|
||||
def test_overlaps_interval(self, constructor, start_shift, closed, other_closed):
|
||||
start, shift = start_shift
|
||||
interval = Interval(start, start + 3 * shift, other_closed)
|
||||
|
||||
# intervals: identical, nested, spanning, partial, adjacent, disjoint
|
||||
tuples = [
|
||||
(start, start + 3 * shift),
|
||||
(start + shift, start + 2 * shift),
|
||||
(start - shift, start + 4 * shift),
|
||||
(start + 2 * shift, start + 4 * shift),
|
||||
(start + 3 * shift, start + 4 * shift),
|
||||
(start + 4 * shift, start + 5 * shift),
|
||||
]
|
||||
interval_container = constructor.from_tuples(tuples, closed)
|
||||
|
||||
adjacent = interval.closed_right and interval_container.closed_left
|
||||
expected = np.array([True, True, True, True, adjacent, False])
|
||||
result = interval_container.overlaps(interval)
|
||||
tm.assert_numpy_array_equal(result, expected)
|
||||
|
||||
@pytest.mark.parametrize("other_constructor", [IntervalArray, IntervalIndex])
|
||||
def test_overlaps_interval_container(self, constructor, other_constructor):
|
||||
# TODO: modify this test when implemented
|
||||
interval_container = constructor.from_breaks(range(5))
|
||||
other_container = other_constructor.from_breaks(range(5))
|
||||
with pytest.raises(NotImplementedError):
|
||||
interval_container.overlaps(other_container)
|
||||
|
||||
def test_overlaps_na(self, constructor, start_shift):
|
||||
"""NA values are marked as False"""
|
||||
start, shift = start_shift
|
||||
interval = Interval(start, start + shift)
|
||||
|
||||
tuples = [
|
||||
(start, start + shift),
|
||||
np.nan,
|
||||
(start + 2 * shift, start + 3 * shift),
|
||||
]
|
||||
interval_container = constructor.from_tuples(tuples)
|
||||
|
||||
expected = np.array([True, False, False])
|
||||
result = interval_container.overlaps(interval)
|
||||
tm.assert_numpy_array_equal(result, expected)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"other",
|
||||
[10, True, "foo", Timedelta("1 day"), Timestamp("2018-01-01")],
|
||||
ids=lambda x: type(x).__name__,
|
||||
)
|
||||
def test_overlaps_invalid_type(self, constructor, other):
|
||||
interval_container = constructor.from_breaks(range(5))
|
||||
msg = "`other` must be Interval-like, got {other}".format(
|
||||
other=type(other).__name__
|
||||
)
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
interval_container.overlaps(other)
|
Reference in New Issue
Block a user