PageRenderTime 33ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 0ms

/pandas/tests/indexes/interval/test_setops.py

https://github.com/pydata/pandas
Python | 204 lines | 151 code | 37 blank | 16 comment | 12 complexity | 7ce0634f7753989d8987d96fa8eccf9f MD5 | raw file
Possible License(s): BSD-3-Clause
  1. import numpy as np
  2. import pytest
  3. from pandas import (
  4. Index,
  5. IntervalIndex,
  6. Timestamp,
  7. interval_range,
  8. )
  9. import pandas._testing as tm
  10. def monotonic_index(start, end, dtype="int64", closed="right"):
  11. return IntervalIndex.from_breaks(
  12. np.arange(start, end, dtype=dtype), inclusive=closed
  13. )
  14. def empty_index(dtype="int64", closed="right"):
  15. return IntervalIndex(np.array([], dtype=dtype), inclusive=closed)
  16. class TestIntervalIndex:
  17. def test_union(self, closed, sort):
  18. index = monotonic_index(0, 11, closed=closed)
  19. other = monotonic_index(5, 13, closed=closed)
  20. expected = monotonic_index(0, 13, closed=closed)
  21. result = index[::-1].union(other, sort=sort)
  22. if sort is None:
  23. tm.assert_index_equal(result, expected)
  24. assert tm.equalContents(result, expected)
  25. result = other[::-1].union(index, sort=sort)
  26. if sort is None:
  27. tm.assert_index_equal(result, expected)
  28. assert tm.equalContents(result, expected)
  29. tm.assert_index_equal(index.union(index, sort=sort), index)
  30. tm.assert_index_equal(index.union(index[:1], sort=sort), index)
  31. def test_union_empty_result(self, closed, sort):
  32. # GH 19101: empty result, same dtype
  33. index = empty_index(dtype="int64", closed=closed)
  34. result = index.union(index, sort=sort)
  35. tm.assert_index_equal(result, index)
  36. # GH 19101: empty result, different numeric dtypes -> common dtype is f8
  37. other = empty_index(dtype="float64", closed=closed)
  38. result = index.union(other, sort=sort)
  39. expected = other
  40. tm.assert_index_equal(result, expected)
  41. other = index.union(index, sort=sort)
  42. tm.assert_index_equal(result, expected)
  43. other = empty_index(dtype="uint64", closed=closed)
  44. result = index.union(other, sort=sort)
  45. tm.assert_index_equal(result, expected)
  46. result = other.union(index, sort=sort)
  47. tm.assert_index_equal(result, expected)
  48. def test_intersection(self, closed, sort):
  49. index = monotonic_index(0, 11, closed=closed)
  50. other = monotonic_index(5, 13, closed=closed)
  51. expected = monotonic_index(5, 11, closed=closed)
  52. result = index[::-1].intersection(other, sort=sort)
  53. if sort is None:
  54. tm.assert_index_equal(result, expected)
  55. assert tm.equalContents(result, expected)
  56. result = other[::-1].intersection(index, sort=sort)
  57. if sort is None:
  58. tm.assert_index_equal(result, expected)
  59. assert tm.equalContents(result, expected)
  60. tm.assert_index_equal(index.intersection(index, sort=sort), index)
  61. # GH 26225: nested intervals
  62. index = IntervalIndex.from_tuples([(1, 2), (1, 3), (1, 4), (0, 2)])
  63. other = IntervalIndex.from_tuples([(1, 2), (1, 3)])
  64. expected = IntervalIndex.from_tuples([(1, 2), (1, 3)])
  65. result = index.intersection(other)
  66. tm.assert_index_equal(result, expected)
  67. # GH 26225
  68. index = IntervalIndex.from_tuples([(0, 3), (0, 2)])
  69. other = IntervalIndex.from_tuples([(0, 2), (1, 3)])
  70. expected = IntervalIndex.from_tuples([(0, 2)])
  71. result = index.intersection(other)
  72. tm.assert_index_equal(result, expected)
  73. # GH 26225: duplicate nan element
  74. index = IntervalIndex([np.nan, np.nan])
  75. other = IntervalIndex([np.nan])
  76. expected = IntervalIndex([np.nan])
  77. result = index.intersection(other)
  78. tm.assert_index_equal(result, expected)
  79. def test_intersection_empty_result(self, closed, sort):
  80. index = monotonic_index(0, 11, closed=closed)
  81. # GH 19101: empty result, same dtype
  82. other = monotonic_index(300, 314, closed=closed)
  83. expected = empty_index(dtype="int64", closed=closed)
  84. result = index.intersection(other, sort=sort)
  85. tm.assert_index_equal(result, expected)
  86. # GH 19101: empty result, different numeric dtypes -> common dtype is float64
  87. other = monotonic_index(300, 314, dtype="float64", closed=closed)
  88. result = index.intersection(other, sort=sort)
  89. expected = other[:0]
  90. tm.assert_index_equal(result, expected)
  91. other = monotonic_index(300, 314, dtype="uint64", closed=closed)
  92. result = index.intersection(other, sort=sort)
  93. tm.assert_index_equal(result, expected)
  94. def test_intersection_duplicates(self):
  95. # GH#38743
  96. index = IntervalIndex.from_tuples([(1, 2), (1, 2), (2, 3), (3, 4)])
  97. other = IntervalIndex.from_tuples([(1, 2), (2, 3)])
  98. expected = IntervalIndex.from_tuples([(1, 2), (2, 3)])
  99. result = index.intersection(other)
  100. tm.assert_index_equal(result, expected)
  101. def test_difference(self, closed, sort):
  102. index = IntervalIndex.from_arrays([1, 0, 3, 2], [1, 2, 3, 4], inclusive=closed)
  103. result = index.difference(index[:1], sort=sort)
  104. expected = index[1:]
  105. if sort is None:
  106. expected = expected.sort_values()
  107. tm.assert_index_equal(result, expected)
  108. # GH 19101: empty result, same dtype
  109. result = index.difference(index, sort=sort)
  110. expected = empty_index(dtype="int64", closed=closed)
  111. tm.assert_index_equal(result, expected)
  112. # GH 19101: empty result, different dtypes
  113. other = IntervalIndex.from_arrays(
  114. index.left.astype("float64"), index.right, inclusive=closed
  115. )
  116. result = index.difference(other, sort=sort)
  117. tm.assert_index_equal(result, expected)
  118. def test_symmetric_difference(self, closed, sort):
  119. index = monotonic_index(0, 11, closed=closed)
  120. result = index[1:].symmetric_difference(index[:-1], sort=sort)
  121. expected = IntervalIndex([index[0], index[-1]])
  122. if sort is None:
  123. tm.assert_index_equal(result, expected)
  124. assert tm.equalContents(result, expected)
  125. # GH 19101: empty result, same dtype
  126. result = index.symmetric_difference(index, sort=sort)
  127. expected = empty_index(dtype="int64", closed=closed)
  128. if sort is None:
  129. tm.assert_index_equal(result, expected)
  130. assert tm.equalContents(result, expected)
  131. # GH 19101: empty result, different dtypes
  132. other = IntervalIndex.from_arrays(
  133. index.left.astype("float64"), index.right, inclusive=closed
  134. )
  135. result = index.symmetric_difference(other, sort=sort)
  136. expected = empty_index(dtype="float64", closed=closed)
  137. tm.assert_index_equal(result, expected)
  138. @pytest.mark.filterwarnings("ignore:'<' not supported between:RuntimeWarning")
  139. @pytest.mark.parametrize(
  140. "op_name", ["union", "intersection", "difference", "symmetric_difference"]
  141. )
  142. def test_set_incompatible_types(self, closed, op_name, sort):
  143. index = monotonic_index(0, 11, closed=closed)
  144. set_op = getattr(index, op_name)
  145. # TODO: standardize return type of non-union setops type(self vs other)
  146. # non-IntervalIndex
  147. if op_name == "difference":
  148. expected = index
  149. else:
  150. expected = getattr(index.astype("O"), op_name)(Index([1, 2, 3]))
  151. result = set_op(Index([1, 2, 3]), sort=sort)
  152. tm.assert_index_equal(result, expected)
  153. # mixed closed -> cast to object
  154. for other_closed in {"right", "left", "both", "neither"} - {closed}:
  155. other = monotonic_index(0, 11, closed=other_closed)
  156. expected = getattr(index.astype(object), op_name)(other, sort=sort)
  157. if op_name == "difference":
  158. expected = index
  159. result = set_op(other, sort=sort)
  160. tm.assert_index_equal(result, expected)
  161. # GH 19016: incompatible dtypes -> cast to object
  162. other = interval_range(Timestamp("20180101"), periods=9, inclusive=closed)
  163. expected = getattr(index.astype(object), op_name)(other, sort=sort)
  164. if op_name == "difference":
  165. expected = index
  166. result = set_op(other, sort=sort)
  167. tm.assert_index_equal(result, expected)