from __future__ import division import pytest import numpy as np from functools import partial from pandas import ( Interval, IntervalIndex, Index, Int64Index, Float64Index, Categorical, CategoricalIndex, date_range, timedelta_range, period_range, notna) from pandas.compat import lzip from pandas.core.dtypes.common import is_categorical_dtype from pandas.core.dtypes.dtypes import IntervalDtype import pandas.core.common as com import pandas.util.testing as tm @pytest.fixture(params=['left', 'right', 'both', 'neither']) def closed(request): return request.param @pytest.fixture(params=[None, 'foo']) def name(request): return request.param class Base(object): """ Common tests for all variations of IntervalIndex construction. Input data to be supplied in breaks format, then converted by the subclass method get_kwargs_from_breaks to the expected format. """ @pytest.mark.parametrize('breaks', [ [3, 14, 15, 92, 653], np.arange(10, dtype='int64'), Int64Index(range(-10, 11)), Float64Index(np.arange(20, 30, 0.5)), date_range('20180101', periods=10), date_range('20180101', periods=10, tz='US/Eastern'), timedelta_range('1 day', periods=10)]) def test_constructor(self, constructor, breaks, closed, name): result_kwargs = self.get_kwargs_from_breaks(breaks, closed) result = constructor(closed=closed, name=name, **result_kwargs) assert result.closed == closed assert result.name == name assert result.dtype.subtype == getattr(breaks, 'dtype', 'int64') tm.assert_index_equal(result.left, Index(breaks[:-1])) tm.assert_index_equal(result.right, Index(breaks[1:])) @pytest.mark.parametrize('breaks, subtype', [ (Int64Index([0, 1, 2, 3, 4]), 'float64'), (Int64Index([0, 1, 2, 3, 4]), 'datetime64[ns]'), (Int64Index([0, 1, 2, 3, 4]), 'timedelta64[ns]'), (Float64Index([0, 1, 2, 3, 4]), 'int64'), (date_range('2017-01-01', periods=5), 'int64'), (timedelta_range('1 day', periods=5), 'int64')]) def test_constructor_dtype(self, constructor, breaks, subtype): # GH 19262: conversion via dtype parameter expected_kwargs = self.get_kwargs_from_breaks(breaks.astype(subtype)) expected = constructor(**expected_kwargs) result_kwargs = self.get_kwargs_from_breaks(breaks) iv_dtype = IntervalDtype(subtype) for dtype in (iv_dtype, str(iv_dtype)): result = constructor(dtype=dtype, **result_kwargs) tm.assert_index_equal(result, expected) @pytest.mark.parametrize('breaks', [ [np.nan] * 2, [np.nan] * 4, [np.nan] * 50]) def test_constructor_nan(self, constructor, breaks, closed): # GH 18421 result_kwargs = self.get_kwargs_from_breaks(breaks) result = constructor(closed=closed, **result_kwargs) expected_subtype = np.float64 expected_values = np.array(breaks[:-1], dtype=object) assert result.closed == closed assert result.dtype.subtype == expected_subtype tm.assert_numpy_array_equal(result.values, expected_values) @pytest.mark.parametrize('breaks', [ [], np.array([], dtype='int64'), np.array([], dtype='float64'), np.array([], dtype='datetime64[ns]'), np.array([], dtype='timedelta64[ns]')]) def test_constructor_empty(self, constructor, breaks, closed): # GH 18421 result_kwargs = self.get_kwargs_from_breaks(breaks) result = constructor(closed=closed, **result_kwargs) expected_values = np.array([], dtype=object) expected_subtype = getattr(breaks, 'dtype', np.int64) assert result.empty assert result.closed == closed assert result.dtype.subtype == expected_subtype tm.assert_numpy_array_equal(result.values, expected_values) @pytest.mark.parametrize('breaks', [ tuple('0123456789'), list('abcdefghij'), np.array(list('abcdefghij'), dtype=object), np.array(list('abcdefghij'), dtype=' with value 0 " "is not an interval") with tm.assert_raises_regex(TypeError, msg): constructor([0, 1]) class TestFromIntervals(TestClassConstructors): """ Tests for IntervalIndex.from_intervals, which is deprecated in favor of the IntervalIndex constructor. Same tests as the IntervalIndex constructor, plus deprecation test. Should only need to delete this class when removed. """ @pytest.fixture def constructor(self): def from_intervals_ignore_warnings(*args, **kwargs): with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): return IntervalIndex.from_intervals(*args, **kwargs) return from_intervals_ignore_warnings def test_deprecated(self): ivs = [Interval(0, 1), Interval(1, 2)] with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): IntervalIndex.from_intervals(ivs)