1import numpy as np 2import pytest 3 4import pandas as pd 5from pandas import Index, MultiIndex 6import pandas._testing as tm 7 8 9def test_reindex(idx): 10 result, indexer = idx.reindex(list(idx[:4])) 11 assert isinstance(result, MultiIndex) 12 assert result.names == ["first", "second"] 13 assert [level.name for level in result.levels] == ["first", "second"] 14 15 result, indexer = idx.reindex(list(idx)) 16 assert isinstance(result, MultiIndex) 17 assert indexer is None 18 assert result.names == ["first", "second"] 19 assert [level.name for level in result.levels] == ["first", "second"] 20 21 22def test_reindex_level(idx): 23 index = Index(["one"]) 24 25 target, indexer = idx.reindex(index, level="second") 26 target2, indexer2 = index.reindex(idx, level="second") 27 28 exp_index = idx.join(index, level="second", how="right") 29 exp_index2 = idx.join(index, level="second", how="left") 30 31 assert target.equals(exp_index) 32 exp_indexer = np.array([0, 2, 4]) 33 tm.assert_numpy_array_equal(indexer, exp_indexer, check_dtype=False) 34 35 assert target2.equals(exp_index2) 36 exp_indexer2 = np.array([0, -1, 0, -1, 0, -1]) 37 tm.assert_numpy_array_equal(indexer2, exp_indexer2, check_dtype=False) 38 39 with pytest.raises(TypeError, match="Fill method not supported"): 40 idx.reindex(idx, method="pad", level="second") 41 42 with pytest.raises(TypeError, match="Fill method not supported"): 43 index.reindex(index, method="bfill", level="first") 44 45 46def test_reindex_preserves_names_when_target_is_list_or_ndarray(idx): 47 # GH6552 48 idx = idx.copy() 49 target = idx.copy() 50 idx.names = target.names = [None, None] 51 52 other_dtype = pd.MultiIndex.from_product([[1, 2], [3, 4]]) 53 54 # list & ndarray cases 55 assert idx.reindex([])[0].names == [None, None] 56 assert idx.reindex(np.array([]))[0].names == [None, None] 57 assert idx.reindex(target.tolist())[0].names == [None, None] 58 assert idx.reindex(target.values)[0].names == [None, None] 59 assert idx.reindex(other_dtype.tolist())[0].names == [None, None] 60 assert idx.reindex(other_dtype.values)[0].names == [None, None] 61 62 idx.names = ["foo", "bar"] 63 assert idx.reindex([])[0].names == ["foo", "bar"] 64 assert idx.reindex(np.array([]))[0].names == ["foo", "bar"] 65 assert idx.reindex(target.tolist())[0].names == ["foo", "bar"] 66 assert idx.reindex(target.values)[0].names == ["foo", "bar"] 67 assert idx.reindex(other_dtype.tolist())[0].names == ["foo", "bar"] 68 assert idx.reindex(other_dtype.values)[0].names == ["foo", "bar"] 69 70 71def test_reindex_lvl_preserves_names_when_target_is_list_or_array(): 72 # GH7774 73 idx = pd.MultiIndex.from_product([[0, 1], ["a", "b"]], names=["foo", "bar"]) 74 assert idx.reindex([], level=0)[0].names == ["foo", "bar"] 75 assert idx.reindex([], level=1)[0].names == ["foo", "bar"] 76 77 78def test_reindex_lvl_preserves_type_if_target_is_empty_list_or_array(): 79 # GH7774 80 idx = pd.MultiIndex.from_product([[0, 1], ["a", "b"]]) 81 assert idx.reindex([], level=0)[0].levels[0].dtype.type == np.int64 82 assert idx.reindex([], level=1)[0].levels[1].dtype.type == np.object_ 83 84 85def test_reindex_base(idx): 86 idx = idx 87 expected = np.arange(idx.size, dtype=np.intp) 88 89 actual = idx.get_indexer(idx) 90 tm.assert_numpy_array_equal(expected, actual) 91 92 with pytest.raises(ValueError, match="Invalid fill method"): 93 idx.get_indexer(idx, method="invalid") 94 95 96def test_reindex_non_unique(): 97 idx = pd.MultiIndex.from_tuples([(0, 0), (1, 1), (1, 1), (2, 2)]) 98 a = pd.Series(np.arange(4), index=idx) 99 new_idx = pd.MultiIndex.from_tuples([(0, 0), (1, 1), (2, 2)]) 100 101 msg = "cannot handle a non-unique multi-index!" 102 with pytest.raises(ValueError, match=msg): 103 a.reindex(new_idx) 104