1import numpy as np 2import pytest 3 4import pandas as pd 5from pandas import Index, MultiIndex, Series 6import pandas._testing as tm 7 8 9def test_equals(idx): 10 assert idx.equals(idx) 11 assert idx.equals(idx.copy()) 12 assert idx.equals(idx.astype(object)) 13 14 assert not idx.equals(list(idx)) 15 assert not idx.equals(np.array(idx)) 16 17 same_values = Index(idx, dtype=object) 18 assert idx.equals(same_values) 19 assert same_values.equals(idx) 20 21 if idx.nlevels == 1: 22 # do not test MultiIndex 23 assert not idx.equals(Series(idx)) 24 25 26def test_equals_op(idx): 27 # GH9947, GH10637 28 index_a = idx 29 30 n = len(index_a) 31 index_b = index_a[0:-1] 32 index_c = index_a[0:-1].append(index_a[-2:-1]) 33 index_d = index_a[0:1] 34 with pytest.raises(ValueError, match="Lengths must match"): 35 index_a == index_b 36 expected1 = np.array([True] * n) 37 expected2 = np.array([True] * (n - 1) + [False]) 38 tm.assert_numpy_array_equal(index_a == index_a, expected1) 39 tm.assert_numpy_array_equal(index_a == index_c, expected2) 40 41 # test comparisons with numpy arrays 42 array_a = np.array(index_a) 43 array_b = np.array(index_a[0:-1]) 44 array_c = np.array(index_a[0:-1].append(index_a[-2:-1])) 45 array_d = np.array(index_a[0:1]) 46 with pytest.raises(ValueError, match="Lengths must match"): 47 index_a == array_b 48 tm.assert_numpy_array_equal(index_a == array_a, expected1) 49 tm.assert_numpy_array_equal(index_a == array_c, expected2) 50 51 # test comparisons with Series 52 series_a = Series(array_a) 53 series_b = Series(array_b) 54 series_c = Series(array_c) 55 series_d = Series(array_d) 56 with pytest.raises(ValueError, match="Lengths must match"): 57 index_a == series_b 58 59 tm.assert_numpy_array_equal(index_a == series_a, expected1) 60 tm.assert_numpy_array_equal(index_a == series_c, expected2) 61 62 # cases where length is 1 for one of them 63 with pytest.raises(ValueError, match="Lengths must match"): 64 index_a == index_d 65 with pytest.raises(ValueError, match="Lengths must match"): 66 index_a == series_d 67 with pytest.raises(ValueError, match="Lengths must match"): 68 index_a == array_d 69 msg = "Can only compare identically-labeled Series objects" 70 with pytest.raises(ValueError, match=msg): 71 series_a == series_d 72 with pytest.raises(ValueError, match="Lengths must match"): 73 series_a == array_d 74 75 # comparing with a scalar should broadcast; note that we are excluding 76 # MultiIndex because in this case each item in the index is a tuple of 77 # length 2, and therefore is considered an array of length 2 in the 78 # comparison instead of a scalar 79 if not isinstance(index_a, MultiIndex): 80 expected3 = np.array([False] * (len(index_a) - 2) + [True, False]) 81 # assuming the 2nd to last item is unique in the data 82 item = index_a[-2] 83 tm.assert_numpy_array_equal(index_a == item, expected3) 84 tm.assert_series_equal(series_a == item, Series(expected3)) 85 86 87def test_compare_tuple(): 88 # GH#21517 89 mi = MultiIndex.from_product([[1, 2]] * 2) 90 91 all_false = np.array([False, False, False, False]) 92 93 result = mi == mi[0] 94 expected = np.array([True, False, False, False]) 95 tm.assert_numpy_array_equal(result, expected) 96 97 result = mi != mi[0] 98 tm.assert_numpy_array_equal(result, ~expected) 99 100 result = mi < mi[0] 101 tm.assert_numpy_array_equal(result, all_false) 102 103 result = mi <= mi[0] 104 tm.assert_numpy_array_equal(result, expected) 105 106 result = mi > mi[0] 107 tm.assert_numpy_array_equal(result, ~expected) 108 109 result = mi >= mi[0] 110 tm.assert_numpy_array_equal(result, ~all_false) 111 112 113def test_compare_tuple_strs(): 114 # GH#34180 115 116 mi = MultiIndex.from_tuples([("a", "b"), ("b", "c"), ("c", "a")]) 117 118 result = mi == ("c", "a") 119 expected = np.array([False, False, True]) 120 tm.assert_numpy_array_equal(result, expected) 121 122 result = mi == ("c",) 123 expected = np.array([False, False, False]) 124 tm.assert_numpy_array_equal(result, expected) 125 126 127def test_equals_multi(idx): 128 assert idx.equals(idx) 129 assert not idx.equals(idx.values) 130 assert idx.equals(Index(idx.values)) 131 132 assert idx.equal_levels(idx) 133 assert not idx.equals(idx[:-1]) 134 assert not idx.equals(idx[-1]) 135 136 # different number of levels 137 index = MultiIndex( 138 levels=[Index(list(range(4))), Index(list(range(4))), Index(list(range(4)))], 139 codes=[ 140 np.array([0, 0, 1, 2, 2, 2, 3, 3]), 141 np.array([0, 1, 0, 0, 0, 1, 0, 1]), 142 np.array([1, 0, 1, 1, 0, 0, 1, 0]), 143 ], 144 ) 145 146 index2 = MultiIndex(levels=index.levels[:-1], codes=index.codes[:-1]) 147 assert not index.equals(index2) 148 assert not index.equal_levels(index2) 149 150 # levels are different 151 major_axis = Index(list(range(4))) 152 minor_axis = Index(list(range(2))) 153 154 major_codes = np.array([0, 0, 1, 2, 2, 3]) 155 minor_codes = np.array([0, 1, 0, 0, 1, 0]) 156 157 index = MultiIndex( 158 levels=[major_axis, minor_axis], codes=[major_codes, minor_codes] 159 ) 160 assert not idx.equals(index) 161 assert not idx.equal_levels(index) 162 163 # some of the labels are different 164 major_axis = Index(["foo", "bar", "baz", "qux"]) 165 minor_axis = Index(["one", "two"]) 166 167 major_codes = np.array([0, 0, 2, 2, 3, 3]) 168 minor_codes = np.array([0, 1, 0, 1, 0, 1]) 169 170 index = MultiIndex( 171 levels=[major_axis, minor_axis], codes=[major_codes, minor_codes] 172 ) 173 assert not idx.equals(index) 174 175 176def test_identical(idx): 177 mi = idx.copy() 178 mi2 = idx.copy() 179 assert mi.identical(mi2) 180 181 mi = mi.set_names(["new1", "new2"]) 182 assert mi.equals(mi2) 183 assert not mi.identical(mi2) 184 185 mi2 = mi2.set_names(["new1", "new2"]) 186 assert mi.identical(mi2) 187 188 mi3 = Index(mi.tolist(), names=mi.names) 189 msg = r"Unexpected keyword arguments {'names'}" 190 with pytest.raises(TypeError, match=msg): 191 Index(mi.tolist(), names=mi.names, tupleize_cols=False) 192 mi4 = Index(mi.tolist(), tupleize_cols=False) 193 assert mi.identical(mi3) 194 assert not mi.identical(mi4) 195 assert mi.equals(mi4) 196 197 198def test_equals_operator(idx): 199 # GH9785 200 assert (idx == idx).all() 201 202 203def test_equals_missing_values(): 204 # make sure take is not using -1 205 i = MultiIndex.from_tuples([(0, pd.NaT), (0, pd.Timestamp("20130101"))]) 206 result = i[0:1].equals(i[0]) 207 assert not result 208 result = i[1:2].equals(i[1]) 209 assert not result 210 211 212def test_is_(): 213 mi = MultiIndex.from_tuples(zip(range(10), range(10))) 214 assert mi.is_(mi) 215 assert mi.is_(mi.view()) 216 assert mi.is_(mi.view().view().view().view()) 217 mi2 = mi.view() 218 # names are metadata, they don't change id 219 mi2.names = ["A", "B"] 220 assert mi2.is_(mi) 221 assert mi.is_(mi2) 222 223 assert not mi.is_(mi.set_names(["C", "D"])) 224 mi2 = mi.view() 225 mi2.set_names(["E", "F"], inplace=True) 226 assert mi.is_(mi2) 227 # levels are inherent properties, they change identity 228 mi3 = mi2.set_levels([list(range(10)), list(range(10))]) 229 assert not mi3.is_(mi2) 230 # shouldn't change 231 assert mi2.is_(mi) 232 mi4 = mi3.view() 233 234 # GH 17464 - Remove duplicate MultiIndex levels 235 with tm.assert_produces_warning(FutureWarning): 236 mi4.set_levels([list(range(10)), list(range(10))], inplace=True) 237 assert not mi4.is_(mi3) 238 mi5 = mi.view() 239 with tm.assert_produces_warning(FutureWarning): 240 mi5.set_levels(mi5.levels, inplace=True) 241 assert not mi5.is_(mi) 242 243 244def test_is_all_dates(idx): 245 assert not idx._is_all_dates 246 247 248def test_is_numeric(idx): 249 # MultiIndex is never numeric 250 assert not idx.is_numeric() 251 252 253def test_multiindex_compare(): 254 # GH 21149 255 # Ensure comparison operations for MultiIndex with nlevels == 1 256 # behave consistently with those for MultiIndex with nlevels > 1 257 258 midx = MultiIndex.from_product([[0, 1]]) 259 260 # Equality self-test: MultiIndex object vs self 261 expected = Series([True, True]) 262 result = Series(midx == midx) 263 tm.assert_series_equal(result, expected) 264 265 # Greater than comparison: MultiIndex object vs self 266 expected = Series([False, False]) 267 result = Series(midx > midx) 268 tm.assert_series_equal(result, expected) 269