test_assert_index_equal.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. import numpy as np
  2. import pytest
  3. from pandas import (
  4. NA,
  5. Categorical,
  6. CategoricalIndex,
  7. Index,
  8. MultiIndex,
  9. NaT,
  10. RangeIndex,
  11. )
  12. import pandas._testing as tm
  13. def test_index_equal_levels_mismatch():
  14. msg = """Index are different
  15. Index levels are different
  16. \\[left\\]: 1, Index\\(\\[1, 2, 3\\], dtype='int64'\\)
  17. \\[right\\]: 2, MultiIndex\\(\\[\\('A', 1\\),
  18. \\('A', 2\\),
  19. \\('B', 3\\),
  20. \\('B', 4\\)\\],
  21. \\)"""
  22. idx1 = Index([1, 2, 3])
  23. idx2 = MultiIndex.from_tuples([("A", 1), ("A", 2), ("B", 3), ("B", 4)])
  24. with pytest.raises(AssertionError, match=msg):
  25. tm.assert_index_equal(idx1, idx2, exact=False)
  26. def test_index_equal_values_mismatch(check_exact):
  27. msg = """MultiIndex level \\[1\\] are different
  28. MultiIndex level \\[1\\] values are different \\(25\\.0 %\\)
  29. \\[left\\]: Index\\(\\[2, 2, 3, 4\\], dtype='int64'\\)
  30. \\[right\\]: Index\\(\\[1, 2, 3, 4\\], dtype='int64'\\)"""
  31. idx1 = MultiIndex.from_tuples([("A", 2), ("A", 2), ("B", 3), ("B", 4)])
  32. idx2 = MultiIndex.from_tuples([("A", 1), ("A", 2), ("B", 3), ("B", 4)])
  33. with pytest.raises(AssertionError, match=msg):
  34. tm.assert_index_equal(idx1, idx2, check_exact=check_exact)
  35. def test_index_equal_length_mismatch(check_exact):
  36. msg = """Index are different
  37. Index length are different
  38. \\[left\\]: 3, Index\\(\\[1, 2, 3\\], dtype='int64'\\)
  39. \\[right\\]: 4, Index\\(\\[1, 2, 3, 4\\], dtype='int64'\\)"""
  40. idx1 = Index([1, 2, 3])
  41. idx2 = Index([1, 2, 3, 4])
  42. with pytest.raises(AssertionError, match=msg):
  43. tm.assert_index_equal(idx1, idx2, check_exact=check_exact)
  44. @pytest.mark.parametrize("exact", [False, "equiv"])
  45. def test_index_equal_class(exact):
  46. idx1 = Index([0, 1, 2])
  47. idx2 = RangeIndex(3)
  48. tm.assert_index_equal(idx1, idx2, exact=exact)
  49. def test_int_float_index_equal_class_mismatch(check_exact):
  50. msg = """Index are different
  51. Attribute "inferred_type" are different
  52. \\[left\\]: integer
  53. \\[right\\]: floating"""
  54. idx1 = Index([1, 2, 3])
  55. idx2 = Index([1, 2, 3], dtype=np.float64)
  56. with pytest.raises(AssertionError, match=msg):
  57. tm.assert_index_equal(idx1, idx2, exact=True, check_exact=check_exact)
  58. def test_range_index_equal_class_mismatch(check_exact):
  59. msg = """Index are different
  60. Index classes are different
  61. \\[left\\]: Index\\(\\[1, 2, 3\\], dtype='int64'\\)
  62. \\[right\\]: """
  63. idx1 = Index([1, 2, 3])
  64. idx2 = RangeIndex(range(3))
  65. with pytest.raises(AssertionError, match=msg):
  66. tm.assert_index_equal(idx1, idx2, exact=True, check_exact=check_exact)
  67. def test_index_equal_values_close(check_exact):
  68. idx1 = Index([1, 2, 3.0])
  69. idx2 = Index([1, 2, 3.0000000001])
  70. if check_exact:
  71. msg = """Index are different
  72. Index values are different \\(33\\.33333 %\\)
  73. \\[left\\]: Index\\(\\[1.0, 2.0, 3.0], dtype='float64'\\)
  74. \\[right\\]: Index\\(\\[1.0, 2.0, 3.0000000001\\], dtype='float64'\\)"""
  75. with pytest.raises(AssertionError, match=msg):
  76. tm.assert_index_equal(idx1, idx2, check_exact=check_exact)
  77. else:
  78. tm.assert_index_equal(idx1, idx2, check_exact=check_exact)
  79. def test_index_equal_values_less_close(check_exact, rtol):
  80. idx1 = Index([1, 2, 3.0])
  81. idx2 = Index([1, 2, 3.0001])
  82. kwargs = {"check_exact": check_exact, "rtol": rtol}
  83. if check_exact or rtol < 0.5e-3:
  84. msg = """Index are different
  85. Index values are different \\(33\\.33333 %\\)
  86. \\[left\\]: Index\\(\\[1.0, 2.0, 3.0], dtype='float64'\\)
  87. \\[right\\]: Index\\(\\[1.0, 2.0, 3.0001\\], dtype='float64'\\)"""
  88. with pytest.raises(AssertionError, match=msg):
  89. tm.assert_index_equal(idx1, idx2, **kwargs)
  90. else:
  91. tm.assert_index_equal(idx1, idx2, **kwargs)
  92. def test_index_equal_values_too_far(check_exact, rtol):
  93. idx1 = Index([1, 2, 3])
  94. idx2 = Index([1, 2, 4])
  95. kwargs = {"check_exact": check_exact, "rtol": rtol}
  96. msg = """Index are different
  97. Index values are different \\(33\\.33333 %\\)
  98. \\[left\\]: Index\\(\\[1, 2, 3\\], dtype='int64'\\)
  99. \\[right\\]: Index\\(\\[1, 2, 4\\], dtype='int64'\\)"""
  100. with pytest.raises(AssertionError, match=msg):
  101. tm.assert_index_equal(idx1, idx2, **kwargs)
  102. @pytest.mark.parametrize("check_order", [True, False])
  103. def test_index_equal_value_oder_mismatch(check_exact, rtol, check_order):
  104. idx1 = Index([1, 2, 3])
  105. idx2 = Index([3, 2, 1])
  106. msg = """Index are different
  107. Index values are different \\(66\\.66667 %\\)
  108. \\[left\\]: Index\\(\\[1, 2, 3\\], dtype='int64'\\)
  109. \\[right\\]: Index\\(\\[3, 2, 1\\], dtype='int64'\\)"""
  110. if check_order:
  111. with pytest.raises(AssertionError, match=msg):
  112. tm.assert_index_equal(
  113. idx1, idx2, check_exact=check_exact, rtol=rtol, check_order=True
  114. )
  115. else:
  116. tm.assert_index_equal(
  117. idx1, idx2, check_exact=check_exact, rtol=rtol, check_order=False
  118. )
  119. def test_index_equal_level_values_mismatch(check_exact, rtol):
  120. idx1 = MultiIndex.from_tuples([("A", 2), ("A", 2), ("B", 3), ("B", 4)])
  121. idx2 = MultiIndex.from_tuples([("A", 1), ("A", 2), ("B", 3), ("B", 4)])
  122. kwargs = {"check_exact": check_exact, "rtol": rtol}
  123. msg = """MultiIndex level \\[1\\] are different
  124. MultiIndex level \\[1\\] values are different \\(25\\.0 %\\)
  125. \\[left\\]: Index\\(\\[2, 2, 3, 4\\], dtype='int64'\\)
  126. \\[right\\]: Index\\(\\[1, 2, 3, 4\\], dtype='int64'\\)"""
  127. with pytest.raises(AssertionError, match=msg):
  128. tm.assert_index_equal(idx1, idx2, **kwargs)
  129. @pytest.mark.parametrize(
  130. "name1,name2",
  131. [(None, "x"), ("x", "x"), (np.nan, np.nan), (NaT, NaT), (np.nan, NaT)],
  132. )
  133. def test_index_equal_names(name1, name2):
  134. idx1 = Index([1, 2, 3], name=name1)
  135. idx2 = Index([1, 2, 3], name=name2)
  136. if name1 == name2 or name1 is name2:
  137. tm.assert_index_equal(idx1, idx2)
  138. else:
  139. name1 = "'x'" if name1 == "x" else name1
  140. name2 = "'x'" if name2 == "x" else name2
  141. msg = f"""Index are different
  142. Attribute "names" are different
  143. \\[left\\]: \\[{name1}\\]
  144. \\[right\\]: \\[{name2}\\]"""
  145. with pytest.raises(AssertionError, match=msg):
  146. tm.assert_index_equal(idx1, idx2)
  147. def test_index_equal_category_mismatch(check_categorical):
  148. msg = """Index are different
  149. Attribute "dtype" are different
  150. \\[left\\]: CategoricalDtype\\(categories=\\['a', 'b'\\], ordered=False\\)
  151. \\[right\\]: CategoricalDtype\\(categories=\\['a', 'b', 'c'\\], \
  152. ordered=False\\)"""
  153. idx1 = Index(Categorical(["a", "b"]))
  154. idx2 = Index(Categorical(["a", "b"], categories=["a", "b", "c"]))
  155. if check_categorical:
  156. with pytest.raises(AssertionError, match=msg):
  157. tm.assert_index_equal(idx1, idx2, check_categorical=check_categorical)
  158. else:
  159. tm.assert_index_equal(idx1, idx2, check_categorical=check_categorical)
  160. @pytest.mark.parametrize("exact", [False, True])
  161. def test_index_equal_range_categories(check_categorical, exact):
  162. # GH41263
  163. msg = """\
  164. Index are different
  165. Index classes are different
  166. \\[left\\]: RangeIndex\\(start=0, stop=10, step=1\\)
  167. \\[right\\]: Index\\(\\[0, 1, 2, 3, 4, 5, 6, 7, 8, 9\\], dtype='int64'\\)"""
  168. rcat = CategoricalIndex(RangeIndex(10))
  169. icat = CategoricalIndex(list(range(10)))
  170. if check_categorical and exact:
  171. with pytest.raises(AssertionError, match=msg):
  172. tm.assert_index_equal(rcat, icat, check_categorical=True, exact=True)
  173. else:
  174. tm.assert_index_equal(
  175. rcat, icat, check_categorical=check_categorical, exact=exact
  176. )
  177. def test_assert_index_equal_different_inferred_types():
  178. # GH#31884
  179. msg = """\
  180. Index are different
  181. Attribute "inferred_type" are different
  182. \\[left\\]: mixed
  183. \\[right\\]: datetime"""
  184. idx1 = Index([NA, np.datetime64("nat")])
  185. idx2 = Index([NA, NaT])
  186. with pytest.raises(AssertionError, match=msg):
  187. tm.assert_index_equal(idx1, idx2)
  188. def test_assert_index_equal_different_names_check_order_false():
  189. # GH#47328
  190. idx1 = Index([1, 3], name="a")
  191. idx2 = Index([3, 1], name="b")
  192. with pytest.raises(AssertionError, match='"names" are different'):
  193. tm.assert_index_equal(idx1, idx2, check_order=False, check_names=True)
  194. def test_assert_index_equal_mixed_dtype():
  195. # GH#39168
  196. idx = Index(["foo", "bar", 42])
  197. tm.assert_index_equal(idx, idx, check_order=False)
  198. def test_assert_index_equal_ea_dtype_order_false(any_numeric_ea_dtype):
  199. # GH#47207
  200. idx1 = Index([1, 3], dtype=any_numeric_ea_dtype)
  201. idx2 = Index([3, 1], dtype=any_numeric_ea_dtype)
  202. tm.assert_index_equal(idx1, idx2, check_order=False)
  203. def test_assert_index_equal_object_ints_order_false():
  204. # GH#47207
  205. idx1 = Index([1, 3], dtype="object")
  206. idx2 = Index([3, 1], dtype="object")
  207. tm.assert_index_equal(idx1, idx2, check_order=False)
  208. @pytest.mark.parametrize("check_categorical", [True, False])
  209. @pytest.mark.parametrize("check_names", [True, False])
  210. def test_assert_ea_index_equal_non_matching_na(check_names, check_categorical):
  211. # GH#48608
  212. idx1 = Index([1, 2], dtype="Int64")
  213. idx2 = Index([1, NA], dtype="Int64")
  214. with pytest.raises(AssertionError, match="50.0 %"):
  215. tm.assert_index_equal(
  216. idx1, idx2, check_names=check_names, check_categorical=check_categorical
  217. )