690 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			690 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import numpy as np
 | 
						|
import pytest
 | 
						|
 | 
						|
from pandas._libs.tslibs import Timestamp
 | 
						|
 | 
						|
import pandas as pd
 | 
						|
from pandas import (
 | 
						|
    Index,
 | 
						|
    Series,
 | 
						|
)
 | 
						|
import pandas._testing as tm
 | 
						|
from pandas.core.indexes.api import (
 | 
						|
    Float64Index,
 | 
						|
    Int64Index,
 | 
						|
    NumericIndex,
 | 
						|
    UInt64Index,
 | 
						|
)
 | 
						|
from pandas.tests.indexes.common import NumericBase
 | 
						|
 | 
						|
 | 
						|
class TestFloatNumericIndex(NumericBase):
 | 
						|
    _index_cls = NumericIndex
 | 
						|
 | 
						|
    @pytest.fixture(params=[np.float64, np.float32])
 | 
						|
    def dtype(self, request):
 | 
						|
        return request.param
 | 
						|
 | 
						|
    @pytest.fixture(params=["category", "datetime64", "object"])
 | 
						|
    def invalid_dtype(self, request):
 | 
						|
        return request.param
 | 
						|
 | 
						|
    @pytest.fixture
 | 
						|
    def simple_index(self, dtype):
 | 
						|
        values = np.arange(5, dtype=dtype)
 | 
						|
        return self._index_cls(values)
 | 
						|
 | 
						|
    @pytest.fixture(
 | 
						|
        params=[
 | 
						|
            [1.5, 2, 3, 4, 5],
 | 
						|
            [0.0, 2.5, 5.0, 7.5, 10.0],
 | 
						|
            [5, 4, 3, 2, 1.5],
 | 
						|
            [10.0, 7.5, 5.0, 2.5, 0.0],
 | 
						|
        ],
 | 
						|
        ids=["mixed", "float", "mixed_dec", "float_dec"],
 | 
						|
    )
 | 
						|
    def index(self, request, dtype):
 | 
						|
        return self._index_cls(request.param, dtype=dtype)
 | 
						|
 | 
						|
    @pytest.fixture
 | 
						|
    def mixed_index(self, dtype):
 | 
						|
        return self._index_cls([1.5, 2, 3, 4, 5], dtype=dtype)
 | 
						|
 | 
						|
    @pytest.fixture
 | 
						|
    def float_index(self, dtype):
 | 
						|
        return self._index_cls([0.0, 2.5, 5.0, 7.5, 10.0], dtype=dtype)
 | 
						|
 | 
						|
    def test_repr_roundtrip(self, index):
 | 
						|
        tm.assert_index_equal(eval(repr(index)), index, exact=True)
 | 
						|
 | 
						|
    def check_is_index(self, idx):
 | 
						|
        assert isinstance(idx, Index)
 | 
						|
        assert not isinstance(idx, self._index_cls)
 | 
						|
 | 
						|
    def check_coerce(self, a, b, is_float_index=True):
 | 
						|
        assert a.equals(b)
 | 
						|
        tm.assert_index_equal(a, b, exact=False)
 | 
						|
        if is_float_index:
 | 
						|
            assert isinstance(b, self._index_cls)
 | 
						|
        else:
 | 
						|
            self.check_is_index(b)
 | 
						|
 | 
						|
    def test_constructor(self, dtype):
 | 
						|
        index_cls = self._index_cls
 | 
						|
 | 
						|
        # explicit construction
 | 
						|
        index = index_cls([1, 2, 3, 4, 5], dtype=dtype)
 | 
						|
 | 
						|
        assert isinstance(index, index_cls)
 | 
						|
        assert index.dtype == dtype
 | 
						|
 | 
						|
        expected = np.array([1, 2, 3, 4, 5], dtype=dtype)
 | 
						|
        tm.assert_numpy_array_equal(index.values, expected)
 | 
						|
 | 
						|
        index = index_cls(np.array([1, 2, 3, 4, 5]), dtype=dtype)
 | 
						|
        assert isinstance(index, index_cls)
 | 
						|
        assert index.dtype == dtype
 | 
						|
 | 
						|
        index = index_cls([1.0, 2, 3, 4, 5], dtype=dtype)
 | 
						|
        assert isinstance(index, index_cls)
 | 
						|
        assert index.dtype == dtype
 | 
						|
 | 
						|
        index = index_cls(np.array([1.0, 2, 3, 4, 5]), dtype=dtype)
 | 
						|
        assert isinstance(index, index_cls)
 | 
						|
        assert index.dtype == dtype
 | 
						|
 | 
						|
        index = index_cls([1.0, 2, 3, 4, 5], dtype=dtype)
 | 
						|
        assert isinstance(index, index_cls)
 | 
						|
        assert index.dtype == dtype
 | 
						|
 | 
						|
        index = index_cls(np.array([1.0, 2, 3, 4, 5]), dtype=dtype)
 | 
						|
        assert isinstance(index, index_cls)
 | 
						|
        assert index.dtype == dtype
 | 
						|
 | 
						|
        # nan handling
 | 
						|
        result = index_cls([np.nan, np.nan], dtype=dtype)
 | 
						|
        assert pd.isna(result.values).all()
 | 
						|
 | 
						|
        result = index_cls(np.array([np.nan]), dtype=dtype)
 | 
						|
        assert pd.isna(result.values).all()
 | 
						|
 | 
						|
    def test_constructor_invalid(self):
 | 
						|
        index_cls = self._index_cls
 | 
						|
        cls_name = index_cls.__name__
 | 
						|
 | 
						|
        # invalid
 | 
						|
        msg = (
 | 
						|
            rf"{cls_name}\(\.\.\.\) must be called with a collection of "
 | 
						|
            r"some kind, 0\.0 was passed"
 | 
						|
        )
 | 
						|
        with pytest.raises(TypeError, match=msg):
 | 
						|
            index_cls(0.0)
 | 
						|
 | 
						|
        # 2021-02-1 we get ValueError in numpy 1.20, but not on all builds
 | 
						|
        msg = "|".join(
 | 
						|
            [
 | 
						|
                "String dtype not supported, you may need to explicitly cast ",
 | 
						|
                "could not convert string to float: 'a'",
 | 
						|
            ]
 | 
						|
        )
 | 
						|
        with pytest.raises((TypeError, ValueError), match=msg):
 | 
						|
            index_cls(["a", "b", 0.0])
 | 
						|
 | 
						|
        msg = f"data is not compatible with {index_cls.__name__}"
 | 
						|
        with pytest.raises(ValueError, match=msg):
 | 
						|
            index_cls([Timestamp("20130101")])
 | 
						|
 | 
						|
    def test_constructor_coerce(self, mixed_index, float_index):
 | 
						|
 | 
						|
        self.check_coerce(mixed_index, Index([1.5, 2, 3, 4, 5]))
 | 
						|
        self.check_coerce(float_index, Index(np.arange(5) * 2.5))
 | 
						|
 | 
						|
        with tm.assert_produces_warning(FutureWarning, match="will not infer"):
 | 
						|
            result = Index(np.array(np.arange(5) * 2.5, dtype=object))
 | 
						|
        self.check_coerce(float_index, result.astype("float64"))
 | 
						|
 | 
						|
    def test_constructor_explicit(self, mixed_index, float_index):
 | 
						|
 | 
						|
        # these don't auto convert
 | 
						|
        self.check_coerce(
 | 
						|
            float_index, Index((np.arange(5) * 2.5), dtype=object), is_float_index=False
 | 
						|
        )
 | 
						|
        self.check_coerce(
 | 
						|
            mixed_index, Index([1.5, 2, 3, 4, 5], dtype=object), is_float_index=False
 | 
						|
        )
 | 
						|
 | 
						|
    def test_type_coercion_fail(self, any_int_numpy_dtype):
 | 
						|
        # see gh-15832
 | 
						|
        msg = "Trying to coerce float values to integers"
 | 
						|
        with pytest.raises(ValueError, match=msg):
 | 
						|
            Index([1, 2, 3.5], dtype=any_int_numpy_dtype)
 | 
						|
 | 
						|
    def test_type_coercion_valid(self, float_numpy_dtype):
 | 
						|
        # There is no Float32Index, so we always
 | 
						|
        # generate Float64Index.
 | 
						|
        idx = Index([1, 2, 3.5], dtype=float_numpy_dtype)
 | 
						|
        tm.assert_index_equal(idx, Index([1, 2, 3.5]), exact=True)
 | 
						|
 | 
						|
    def test_equals_numeric(self):
 | 
						|
        index_cls = self._index_cls
 | 
						|
 | 
						|
        idx = index_cls([1.0, 2.0])
 | 
						|
        assert idx.equals(idx)
 | 
						|
        assert idx.identical(idx)
 | 
						|
 | 
						|
        idx2 = index_cls([1.0, 2.0])
 | 
						|
        assert idx.equals(idx2)
 | 
						|
 | 
						|
        idx = index_cls([1.0, np.nan])
 | 
						|
        assert idx.equals(idx)
 | 
						|
        assert idx.identical(idx)
 | 
						|
 | 
						|
        idx2 = index_cls([1.0, np.nan])
 | 
						|
        assert idx.equals(idx2)
 | 
						|
 | 
						|
    @pytest.mark.parametrize(
 | 
						|
        "other",
 | 
						|
        (
 | 
						|
            Int64Index([1, 2]),
 | 
						|
            Index([1.0, 2.0], dtype=object),
 | 
						|
            Index([1, 2], dtype=object),
 | 
						|
        ),
 | 
						|
    )
 | 
						|
    def test_equals_numeric_other_index_type(self, other):
 | 
						|
        idx = self._index_cls([1.0, 2.0])
 | 
						|
        assert idx.equals(other)
 | 
						|
        assert other.equals(idx)
 | 
						|
 | 
						|
    @pytest.mark.parametrize(
 | 
						|
        "vals",
 | 
						|
        [
 | 
						|
            pd.date_range("2016-01-01", periods=3),
 | 
						|
            pd.timedelta_range("1 Day", periods=3),
 | 
						|
        ],
 | 
						|
    )
 | 
						|
    def test_lookups_datetimelike_values(self, vals, dtype):
 | 
						|
 | 
						|
        # If we have datetime64 or timedelta64 values, make sure they are
 | 
						|
        #  wrappped correctly  GH#31163
 | 
						|
        ser = Series(vals, index=range(3, 6))
 | 
						|
        ser.index = ser.index.astype(dtype)
 | 
						|
 | 
						|
        expected = vals[1]
 | 
						|
 | 
						|
        with tm.assert_produces_warning(FutureWarning):
 | 
						|
            result = ser.index.get_value(ser, 4.0)
 | 
						|
        assert isinstance(result, type(expected)) and result == expected
 | 
						|
        with tm.assert_produces_warning(FutureWarning):
 | 
						|
            result = ser.index.get_value(ser, 4)
 | 
						|
        assert isinstance(result, type(expected)) and result == expected
 | 
						|
 | 
						|
        result = ser[4.0]
 | 
						|
        assert isinstance(result, type(expected)) and result == expected
 | 
						|
        result = ser[4]
 | 
						|
        assert isinstance(result, type(expected)) and result == expected
 | 
						|
 | 
						|
        result = ser.loc[4.0]
 | 
						|
        assert isinstance(result, type(expected)) and result == expected
 | 
						|
        result = ser.loc[4]
 | 
						|
        assert isinstance(result, type(expected)) and result == expected
 | 
						|
 | 
						|
        result = ser.at[4.0]
 | 
						|
        assert isinstance(result, type(expected)) and result == expected
 | 
						|
        # GH#31329 .at[4] should cast to 4.0, matching .loc behavior
 | 
						|
        result = ser.at[4]
 | 
						|
        assert isinstance(result, type(expected)) and result == expected
 | 
						|
 | 
						|
        result = ser.iloc[1]
 | 
						|
        assert isinstance(result, type(expected)) and result == expected
 | 
						|
 | 
						|
        result = ser.iat[1]
 | 
						|
        assert isinstance(result, type(expected)) and result == expected
 | 
						|
 | 
						|
    def test_doesnt_contain_all_the_things(self):
 | 
						|
        idx = self._index_cls([np.nan])
 | 
						|
        assert not idx.isin([0]).item()
 | 
						|
        assert not idx.isin([1]).item()
 | 
						|
        assert idx.isin([np.nan]).item()
 | 
						|
 | 
						|
    def test_nan_multiple_containment(self):
 | 
						|
        index_cls = self._index_cls
 | 
						|
 | 
						|
        idx = index_cls([1.0, np.nan])
 | 
						|
        tm.assert_numpy_array_equal(idx.isin([1.0]), np.array([True, False]))
 | 
						|
        tm.assert_numpy_array_equal(idx.isin([2.0, np.pi]), np.array([False, False]))
 | 
						|
        tm.assert_numpy_array_equal(idx.isin([np.nan]), np.array([False, True]))
 | 
						|
        tm.assert_numpy_array_equal(idx.isin([1.0, np.nan]), np.array([True, True]))
 | 
						|
        idx = index_cls([1.0, 2.0])
 | 
						|
        tm.assert_numpy_array_equal(idx.isin([np.nan]), np.array([False, False]))
 | 
						|
 | 
						|
    def test_fillna_float64(self):
 | 
						|
        index_cls = self._index_cls
 | 
						|
        # GH 11343
 | 
						|
        idx = Index([1.0, np.nan, 3.0], dtype=float, name="x")
 | 
						|
        # can't downcast
 | 
						|
        exp = Index([1.0, 0.1, 3.0], name="x")
 | 
						|
        tm.assert_index_equal(idx.fillna(0.1), exp, exact=True)
 | 
						|
 | 
						|
        # downcast
 | 
						|
        exact = True if index_cls is Int64Index else "equiv"
 | 
						|
        exp = index_cls([1.0, 2.0, 3.0], name="x")
 | 
						|
        tm.assert_index_equal(idx.fillna(2), exp, exact=exact)
 | 
						|
 | 
						|
        # object
 | 
						|
        exp = Index([1.0, "obj", 3.0], name="x")
 | 
						|
        tm.assert_index_equal(idx.fillna("obj"), exp, exact=True)
 | 
						|
 | 
						|
 | 
						|
class TestFloat64Index(TestFloatNumericIndex):
 | 
						|
    _index_cls = Float64Index
 | 
						|
 | 
						|
    @pytest.fixture
 | 
						|
    def dtype(self, request):
 | 
						|
        return np.float64
 | 
						|
 | 
						|
    @pytest.fixture(
 | 
						|
        params=["int64", "uint64", "object", "category", "datetime64"],
 | 
						|
    )
 | 
						|
    def invalid_dtype(self, request):
 | 
						|
        return request.param
 | 
						|
 | 
						|
    def test_constructor_from_base_index(self, dtype):
 | 
						|
        index_cls = self._index_cls
 | 
						|
 | 
						|
        result = Index(np.array([np.nan], dtype=dtype))
 | 
						|
        assert isinstance(result, index_cls)
 | 
						|
        assert result.dtype == dtype
 | 
						|
        assert pd.isna(result.values).all()
 | 
						|
 | 
						|
    def test_constructor_32bit(self, dtype):
 | 
						|
        index_cls = self._index_cls
 | 
						|
 | 
						|
        index = index_cls(np.array([1.0, 2, 3, 4, 5]), dtype=np.float32)
 | 
						|
        assert isinstance(index, index_cls)
 | 
						|
        assert index.dtype == np.float64
 | 
						|
 | 
						|
        index = index_cls(np.array([1, 2, 3, 4, 5]), dtype=np.float32)
 | 
						|
        assert isinstance(index, index_cls)
 | 
						|
        assert index.dtype == np.float64
 | 
						|
 | 
						|
 | 
						|
class NumericInt(NumericBase):
 | 
						|
    def test_view(self, dtype):
 | 
						|
        index_cls = self._index_cls
 | 
						|
 | 
						|
        idx = index_cls([], dtype=dtype, name="Foo")
 | 
						|
        idx_view = idx.view()
 | 
						|
        assert idx_view.name == "Foo"
 | 
						|
 | 
						|
        idx_view = idx.view(dtype)
 | 
						|
        tm.assert_index_equal(idx, index_cls(idx_view, name="Foo"), exact=True)
 | 
						|
 | 
						|
        idx_view = idx.view(index_cls)
 | 
						|
        tm.assert_index_equal(idx, index_cls(idx_view, name="Foo"), exact=True)
 | 
						|
 | 
						|
    def test_is_monotonic(self):
 | 
						|
        index_cls = self._index_cls
 | 
						|
 | 
						|
        index = index_cls([1, 2, 3, 4])
 | 
						|
        assert index.is_monotonic is True
 | 
						|
        assert index.is_monotonic_increasing is True
 | 
						|
        assert index._is_strictly_monotonic_increasing is True
 | 
						|
        assert index.is_monotonic_decreasing is False
 | 
						|
        assert index._is_strictly_monotonic_decreasing is False
 | 
						|
 | 
						|
        index = index_cls([4, 3, 2, 1])
 | 
						|
        assert index.is_monotonic is False
 | 
						|
        assert index._is_strictly_monotonic_increasing is False
 | 
						|
        assert index._is_strictly_monotonic_decreasing is True
 | 
						|
 | 
						|
        index = index_cls([1])
 | 
						|
        assert index.is_monotonic is True
 | 
						|
        assert index.is_monotonic_increasing is True
 | 
						|
        assert index.is_monotonic_decreasing is True
 | 
						|
        assert index._is_strictly_monotonic_increasing is True
 | 
						|
        assert index._is_strictly_monotonic_decreasing is True
 | 
						|
 | 
						|
    def test_is_strictly_monotonic(self):
 | 
						|
        index_cls = self._index_cls
 | 
						|
 | 
						|
        index = index_cls([1, 1, 2, 3])
 | 
						|
        assert index.is_monotonic_increasing is True
 | 
						|
        assert index._is_strictly_monotonic_increasing is False
 | 
						|
 | 
						|
        index = index_cls([3, 2, 1, 1])
 | 
						|
        assert index.is_monotonic_decreasing is True
 | 
						|
        assert index._is_strictly_monotonic_decreasing is False
 | 
						|
 | 
						|
        index = index_cls([1, 1])
 | 
						|
        assert index.is_monotonic_increasing
 | 
						|
        assert index.is_monotonic_decreasing
 | 
						|
        assert not index._is_strictly_monotonic_increasing
 | 
						|
        assert not index._is_strictly_monotonic_decreasing
 | 
						|
 | 
						|
    def test_logical_compat(self, simple_index):
 | 
						|
        idx = simple_index
 | 
						|
        assert idx.all() == idx.values.all()
 | 
						|
        assert idx.any() == idx.values.any()
 | 
						|
 | 
						|
    def test_identical(self, simple_index, dtype):
 | 
						|
        index = simple_index
 | 
						|
 | 
						|
        idx = Index(index.copy())
 | 
						|
        assert idx.identical(index)
 | 
						|
 | 
						|
        same_values_different_type = Index(idx, dtype=object)
 | 
						|
        assert not idx.identical(same_values_different_type)
 | 
						|
 | 
						|
        idx = index.astype(dtype=object)
 | 
						|
        idx = idx.rename("foo")
 | 
						|
        same_values = Index(idx, dtype=object)
 | 
						|
        assert same_values.identical(idx)
 | 
						|
 | 
						|
        assert not idx.identical(index)
 | 
						|
        assert Index(same_values, name="foo", dtype=object).identical(idx)
 | 
						|
 | 
						|
        assert not index.astype(dtype=object).identical(index.astype(dtype=dtype))
 | 
						|
 | 
						|
    def test_cant_or_shouldnt_cast(self):
 | 
						|
        msg = (
 | 
						|
            "String dtype not supported, "
 | 
						|
            "you may need to explicitly cast to a numeric type"
 | 
						|
        )
 | 
						|
        # can't
 | 
						|
        data = ["foo", "bar", "baz"]
 | 
						|
        with pytest.raises(TypeError, match=msg):
 | 
						|
            self._index_cls(data)
 | 
						|
 | 
						|
        # shouldn't
 | 
						|
        data = ["0", "1", "2"]
 | 
						|
        with pytest.raises(TypeError, match=msg):
 | 
						|
            self._index_cls(data)
 | 
						|
 | 
						|
    def test_view_index(self, simple_index):
 | 
						|
        index = simple_index
 | 
						|
        index.view(Index)
 | 
						|
 | 
						|
    def test_prevent_casting(self, simple_index):
 | 
						|
        index = simple_index
 | 
						|
        result = index.astype("O")
 | 
						|
        assert result.dtype == np.object_
 | 
						|
 | 
						|
 | 
						|
class TestIntNumericIndex(NumericInt):
 | 
						|
    _index_cls = NumericIndex
 | 
						|
 | 
						|
    @pytest.fixture(params=[np.int64, np.int32, np.int16, np.int8])
 | 
						|
    def dtype(self, request):
 | 
						|
        return request.param
 | 
						|
 | 
						|
    @pytest.fixture(params=["category", "datetime64", "object"])
 | 
						|
    def invalid_dtype(self, request):
 | 
						|
        return request.param
 | 
						|
 | 
						|
    @pytest.fixture
 | 
						|
    def simple_index(self, dtype):
 | 
						|
        return self._index_cls(range(0, 20, 2), dtype=dtype)
 | 
						|
 | 
						|
    @pytest.fixture(
 | 
						|
        params=[range(0, 20, 2), range(19, -1, -1)], ids=["index_inc", "index_dec"]
 | 
						|
    )
 | 
						|
    def index(self, request, dtype):
 | 
						|
        return self._index_cls(request.param, dtype=dtype)
 | 
						|
 | 
						|
    def test_constructor(self, dtype):
 | 
						|
        index_cls = self._index_cls
 | 
						|
 | 
						|
        # scalar raise Exception
 | 
						|
        msg = (
 | 
						|
            rf"{index_cls.__name__}\(\.\.\.\) must be called with a collection of some "
 | 
						|
            "kind, 5 was passed"
 | 
						|
        )
 | 
						|
        with pytest.raises(TypeError, match=msg):
 | 
						|
            index_cls(5)
 | 
						|
 | 
						|
        # copy
 | 
						|
        # pass list, coerce fine
 | 
						|
        index = index_cls([-5, 0, 1, 2], dtype=dtype)
 | 
						|
        arr = index.values
 | 
						|
        new_index = index_cls(arr, copy=True)
 | 
						|
        tm.assert_index_equal(new_index, index, exact=True)
 | 
						|
        val = arr[0] + 3000
 | 
						|
 | 
						|
        # this should not change index
 | 
						|
        arr[0] = val
 | 
						|
        assert new_index[0] != val
 | 
						|
 | 
						|
        if dtype == np.int64:
 | 
						|
            exact = "equiv" if index_cls != Int64Index else True
 | 
						|
 | 
						|
            # pass list, coerce fine
 | 
						|
            index = index_cls([-5, 0, 1, 2], dtype=dtype)
 | 
						|
            expected = Index([-5, 0, 1, 2], dtype=dtype)
 | 
						|
            tm.assert_index_equal(index, expected, exact=exact)
 | 
						|
 | 
						|
            # from iterable
 | 
						|
            index = index_cls(iter([-5, 0, 1, 2]), dtype=dtype)
 | 
						|
            expected = index_cls([-5, 0, 1, 2], dtype=dtype)
 | 
						|
            tm.assert_index_equal(index, expected, exact=exact)
 | 
						|
 | 
						|
            # interpret list-like
 | 
						|
            expected = index_cls([5, 0], dtype=dtype)
 | 
						|
            for cls in [Index, index_cls]:
 | 
						|
                for idx in [
 | 
						|
                    cls([5, 0], dtype=dtype),
 | 
						|
                    cls(np.array([5, 0]), dtype=dtype),
 | 
						|
                    cls(Series([5, 0]), dtype=dtype),
 | 
						|
                ]:
 | 
						|
                    tm.assert_index_equal(idx, expected, exact=exact)
 | 
						|
 | 
						|
    def test_constructor_corner(self, dtype):
 | 
						|
        index_cls = self._index_cls
 | 
						|
 | 
						|
        arr = np.array([1, 2, 3, 4], dtype=object)
 | 
						|
 | 
						|
        index = index_cls(arr, dtype=dtype)
 | 
						|
        assert index.values.dtype == index.dtype
 | 
						|
        if dtype == np.int64:
 | 
						|
 | 
						|
            msg = "will not infer"
 | 
						|
            with tm.assert_produces_warning(FutureWarning, match=msg):
 | 
						|
                without_dtype = Index(arr)
 | 
						|
 | 
						|
            exact = True if index_cls is Int64Index else "equiv"
 | 
						|
            tm.assert_index_equal(index, without_dtype, exact=exact)
 | 
						|
 | 
						|
        # preventing casting
 | 
						|
        arr = np.array([1, "2", 3, "4"], dtype=object)
 | 
						|
        with pytest.raises(TypeError, match="casting"):
 | 
						|
            index_cls(arr, dtype=dtype)
 | 
						|
 | 
						|
    def test_constructor_coercion_signed_to_unsigned(
 | 
						|
        self,
 | 
						|
        any_unsigned_int_numpy_dtype,
 | 
						|
    ):
 | 
						|
 | 
						|
        # see gh-15832
 | 
						|
        msg = "Trying to coerce negative values to unsigned integers"
 | 
						|
 | 
						|
        with pytest.raises(OverflowError, match=msg):
 | 
						|
            Index([-1], dtype=any_unsigned_int_numpy_dtype)
 | 
						|
 | 
						|
    def test_coerce_list(self):
 | 
						|
        # coerce things
 | 
						|
        arr = Index([1, 2, 3, 4])
 | 
						|
        assert isinstance(arr, self._index_cls)
 | 
						|
 | 
						|
        # but not if explicit dtype passed
 | 
						|
        arr = Index([1, 2, 3, 4], dtype=object)
 | 
						|
        assert type(arr) is Index
 | 
						|
 | 
						|
 | 
						|
class TestInt64Index(TestIntNumericIndex):
 | 
						|
    _index_cls = Int64Index
 | 
						|
 | 
						|
    @pytest.fixture
 | 
						|
    def dtype(self):
 | 
						|
        return np.int64
 | 
						|
 | 
						|
    @pytest.fixture(
 | 
						|
        params=["float64", "uint64", "object", "category", "datetime64"],
 | 
						|
    )
 | 
						|
    def invalid_dtype(self, request):
 | 
						|
        return request.param
 | 
						|
 | 
						|
    def test_constructor_32bit(self, dtype):
 | 
						|
        index_cls = self._index_cls
 | 
						|
 | 
						|
        index = index_cls(np.array([1, 2, 3, 4, 5]), dtype=np.int32)
 | 
						|
        assert isinstance(index, index_cls)
 | 
						|
        assert index.dtype == np.int64
 | 
						|
 | 
						|
        index = index_cls(np.array([1, 2, 3, 4, 5]), dtype=np.int32)
 | 
						|
        assert isinstance(index, index_cls)
 | 
						|
        assert index.dtype == np.int64
 | 
						|
 | 
						|
 | 
						|
class TestUIntNumericIndex(NumericInt):
 | 
						|
 | 
						|
    _index_cls = NumericIndex
 | 
						|
 | 
						|
    @pytest.fixture(params=[np.uint64])
 | 
						|
    def dtype(self, request):
 | 
						|
        return request.param
 | 
						|
 | 
						|
    @pytest.fixture(params=["category", "datetime64", "object"])
 | 
						|
    def invalid_dtype(self, request):
 | 
						|
        return request.param
 | 
						|
 | 
						|
    @pytest.fixture
 | 
						|
    def simple_index(self, dtype):
 | 
						|
        # compat with shared Int64/Float64 tests
 | 
						|
        return self._index_cls(np.arange(5, dtype=dtype))
 | 
						|
 | 
						|
    @pytest.fixture(
 | 
						|
        params=[
 | 
						|
            [2**63, 2**63 + 10, 2**63 + 15, 2**63 + 20, 2**63 + 25],
 | 
						|
            [2**63 + 25, 2**63 + 20, 2**63 + 15, 2**63 + 10, 2**63],
 | 
						|
        ],
 | 
						|
        ids=["index_inc", "index_dec"],
 | 
						|
    )
 | 
						|
    def index(self, request):
 | 
						|
        return self._index_cls(request.param, dtype=np.uint64)
 | 
						|
 | 
						|
 | 
						|
class TestUInt64Index(TestUIntNumericIndex):
 | 
						|
 | 
						|
    _index_cls = UInt64Index
 | 
						|
 | 
						|
    @pytest.fixture
 | 
						|
    def dtype(self):
 | 
						|
        return np.uint64
 | 
						|
 | 
						|
    @pytest.fixture(
 | 
						|
        params=["int64", "float64", "object", "category", "datetime64"],
 | 
						|
    )
 | 
						|
    def invalid_dtype(self, request):
 | 
						|
        return request.param
 | 
						|
 | 
						|
    def test_constructor(self, dtype):
 | 
						|
        index_cls = self._index_cls
 | 
						|
        exact = True if index_cls is UInt64Index else "equiv"
 | 
						|
 | 
						|
        idx = index_cls([1, 2, 3])
 | 
						|
        res = Index([1, 2, 3], dtype=dtype)
 | 
						|
        tm.assert_index_equal(res, idx, exact=exact)
 | 
						|
 | 
						|
        idx = index_cls([1, 2**63])
 | 
						|
        res = Index([1, 2**63], dtype=dtype)
 | 
						|
        tm.assert_index_equal(res, idx, exact=exact)
 | 
						|
 | 
						|
        idx = index_cls([1, 2**63])
 | 
						|
        res = Index([1, 2**63])
 | 
						|
        tm.assert_index_equal(res, idx, exact=exact)
 | 
						|
 | 
						|
        idx = Index([-1, 2**63], dtype=object)
 | 
						|
        res = Index(np.array([-1, 2**63], dtype=object))
 | 
						|
        tm.assert_index_equal(res, idx, exact=exact)
 | 
						|
 | 
						|
        # https://github.com/pandas-dev/pandas/issues/29526
 | 
						|
        idx = index_cls([1, 2**63 + 1], dtype=dtype)
 | 
						|
        res = Index([1, 2**63 + 1], dtype=dtype)
 | 
						|
        tm.assert_index_equal(res, idx, exact=exact)
 | 
						|
 | 
						|
    def test_constructor_does_not_cast_to_float(self):
 | 
						|
        # https://github.com/numpy/numpy/issues/19146
 | 
						|
        values = [0, np.iinfo(np.uint64).max]
 | 
						|
 | 
						|
        result = UInt64Index(values)
 | 
						|
        assert list(result) == values
 | 
						|
 | 
						|
    def test_constructor_32bit(self, dtype):
 | 
						|
        index_cls = self._index_cls
 | 
						|
 | 
						|
        index = index_cls(np.array([1, 2, 3, 4, 5]), dtype=np.uint32)
 | 
						|
        assert isinstance(index, index_cls)
 | 
						|
        assert index.dtype == np.uint64
 | 
						|
 | 
						|
        index = index_cls(np.array([1, 2, 3, 4, 5]), dtype=np.uint32)
 | 
						|
        assert isinstance(index, index_cls)
 | 
						|
        assert index.dtype == np.uint64
 | 
						|
 | 
						|
 | 
						|
@pytest.mark.parametrize(
 | 
						|
    "box",
 | 
						|
    [list, lambda x: np.array(x, dtype=object), lambda x: Index(x, dtype=object)],
 | 
						|
)
 | 
						|
def test_uint_index_does_not_convert_to_float64(box):
 | 
						|
    # https://github.com/pandas-dev/pandas/issues/28279
 | 
						|
    # https://github.com/pandas-dev/pandas/issues/28023
 | 
						|
    series = Series(
 | 
						|
        [0, 1, 2, 3, 4, 5],
 | 
						|
        index=[
 | 
						|
            7606741985629028552,
 | 
						|
            17876870360202815256,
 | 
						|
            17876870360202815256,
 | 
						|
            13106359306506049338,
 | 
						|
            8991270399732411471,
 | 
						|
            8991270399732411472,
 | 
						|
        ],
 | 
						|
    )
 | 
						|
 | 
						|
    result = series.loc[box([7606741985629028552, 17876870360202815256])]
 | 
						|
 | 
						|
    expected = UInt64Index(
 | 
						|
        [7606741985629028552, 17876870360202815256, 17876870360202815256],
 | 
						|
        dtype="uint64",
 | 
						|
    )
 | 
						|
    tm.assert_index_equal(result.index, expected)
 | 
						|
 | 
						|
    tm.assert_equal(result, series[:3])
 | 
						|
 | 
						|
 | 
						|
def test_float64_index_equals():
 | 
						|
    # https://github.com/pandas-dev/pandas/issues/35217
 | 
						|
    float_index = Index([1.0, 2, 3])
 | 
						|
    string_index = Index(["1", "2", "3"])
 | 
						|
 | 
						|
    result = float_index.equals(string_index)
 | 
						|
    assert result is False
 | 
						|
 | 
						|
    result = string_index.equals(float_index)
 | 
						|
    assert result is False
 | 
						|
 | 
						|
 | 
						|
def test_map_dtype_inference_unsigned_to_signed():
 | 
						|
    # GH#44609 cases where we don't retain dtype
 | 
						|
    idx = UInt64Index([1, 2, 3])
 | 
						|
    result = idx.map(lambda x: -x)
 | 
						|
    expected = Int64Index([-1, -2, -3])
 | 
						|
    tm.assert_index_equal(result, expected)
 | 
						|
 | 
						|
 | 
						|
def test_map_dtype_inference_overflows():
 | 
						|
    # GH#44609 case where we have to upcast
 | 
						|
    idx = NumericIndex(np.array([1, 2, 3], dtype=np.int8))
 | 
						|
    result = idx.map(lambda x: x * 1000)
 | 
						|
    # TODO: we could plausibly try to infer down to int16 here
 | 
						|
    expected = NumericIndex([1000, 2000, 3000], dtype=np.int64)
 | 
						|
    tm.assert_index_equal(result, expected)
 |