test_monotonic.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. # -*- coding: utf-8 -*-
  2. import numpy as np
  3. import pytest
  4. import pandas as pd
  5. from pandas import Index, IntervalIndex, MultiIndex
  6. from pandas.api.types import is_scalar
  7. def test_is_monotonic_increasing():
  8. i = MultiIndex.from_product([np.arange(10),
  9. np.arange(10)], names=['one', 'two'])
  10. assert i.is_monotonic is True
  11. assert i._is_strictly_monotonic_increasing is True
  12. assert Index(i.values).is_monotonic is True
  13. assert i._is_strictly_monotonic_increasing is True
  14. i = MultiIndex.from_product([np.arange(10, 0, -1),
  15. np.arange(10)], names=['one', 'two'])
  16. assert i.is_monotonic is False
  17. assert i._is_strictly_monotonic_increasing is False
  18. assert Index(i.values).is_monotonic is False
  19. assert Index(i.values)._is_strictly_monotonic_increasing is False
  20. i = MultiIndex.from_product([np.arange(10),
  21. np.arange(10, 0, -1)],
  22. names=['one', 'two'])
  23. assert i.is_monotonic is False
  24. assert i._is_strictly_monotonic_increasing is False
  25. assert Index(i.values).is_monotonic is False
  26. assert Index(i.values)._is_strictly_monotonic_increasing is False
  27. i = MultiIndex.from_product([[1.0, np.nan, 2.0], ['a', 'b', 'c']])
  28. assert i.is_monotonic is False
  29. assert i._is_strictly_monotonic_increasing is False
  30. assert Index(i.values).is_monotonic is False
  31. assert Index(i.values)._is_strictly_monotonic_increasing is False
  32. # string ordering
  33. i = MultiIndex(levels=[['foo', 'bar', 'baz', 'qux'],
  34. ['one', 'two', 'three']],
  35. codes=[[0, 0, 0, 1, 1, 2, 2, 3, 3, 3],
  36. [0, 1, 2, 0, 1, 1, 2, 0, 1, 2]],
  37. names=['first', 'second'])
  38. assert i.is_monotonic is False
  39. assert Index(i.values).is_monotonic is False
  40. assert i._is_strictly_monotonic_increasing is False
  41. assert Index(i.values)._is_strictly_monotonic_increasing is False
  42. i = MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'],
  43. ['mom', 'next', 'zenith']],
  44. codes=[[0, 0, 0, 1, 1, 2, 2, 3, 3, 3],
  45. [0, 1, 2, 0, 1, 1, 2, 0, 1, 2]],
  46. names=['first', 'second'])
  47. assert i.is_monotonic is True
  48. assert Index(i.values).is_monotonic is True
  49. assert i._is_strictly_monotonic_increasing is True
  50. assert Index(i.values)._is_strictly_monotonic_increasing is True
  51. # mixed levels, hits the TypeError
  52. i = MultiIndex(
  53. levels=[[1, 2, 3, 4], ['gb00b03mlx29', 'lu0197800237',
  54. 'nl0000289783',
  55. 'nl0000289965', 'nl0000301109']],
  56. codes=[[0, 1, 1, 2, 2, 2, 3], [4, 2, 0, 0, 1, 3, -1]],
  57. names=['household_id', 'asset_id'])
  58. assert i.is_monotonic is False
  59. assert i._is_strictly_monotonic_increasing is False
  60. # empty
  61. i = MultiIndex.from_arrays([[], []])
  62. assert i.is_monotonic is True
  63. assert Index(i.values).is_monotonic is True
  64. assert i._is_strictly_monotonic_increasing is True
  65. assert Index(i.values)._is_strictly_monotonic_increasing is True
  66. def test_is_monotonic_decreasing():
  67. i = MultiIndex.from_product([np.arange(9, -1, -1),
  68. np.arange(9, -1, -1)],
  69. names=['one', 'two'])
  70. assert i.is_monotonic_decreasing is True
  71. assert i._is_strictly_monotonic_decreasing is True
  72. assert Index(i.values).is_monotonic_decreasing is True
  73. assert i._is_strictly_monotonic_decreasing is True
  74. i = MultiIndex.from_product([np.arange(10),
  75. np.arange(10, 0, -1)],
  76. names=['one', 'two'])
  77. assert i.is_monotonic_decreasing is False
  78. assert i._is_strictly_monotonic_decreasing is False
  79. assert Index(i.values).is_monotonic_decreasing is False
  80. assert Index(i.values)._is_strictly_monotonic_decreasing is False
  81. i = MultiIndex.from_product([np.arange(10, 0, -1),
  82. np.arange(10)], names=['one', 'two'])
  83. assert i.is_monotonic_decreasing is False
  84. assert i._is_strictly_monotonic_decreasing is False
  85. assert Index(i.values).is_monotonic_decreasing is False
  86. assert Index(i.values)._is_strictly_monotonic_decreasing is False
  87. i = MultiIndex.from_product([[2.0, np.nan, 1.0], ['c', 'b', 'a']])
  88. assert i.is_monotonic_decreasing is False
  89. assert i._is_strictly_monotonic_decreasing is False
  90. assert Index(i.values).is_monotonic_decreasing is False
  91. assert Index(i.values)._is_strictly_monotonic_decreasing is False
  92. # string ordering
  93. i = MultiIndex(levels=[['qux', 'foo', 'baz', 'bar'],
  94. ['three', 'two', 'one']],
  95. codes=[[0, 0, 0, 1, 1, 2, 2, 3, 3, 3],
  96. [0, 1, 2, 0, 1, 1, 2, 0, 1, 2]],
  97. names=['first', 'second'])
  98. assert i.is_monotonic_decreasing is False
  99. assert Index(i.values).is_monotonic_decreasing is False
  100. assert i._is_strictly_monotonic_decreasing is False
  101. assert Index(i.values)._is_strictly_monotonic_decreasing is False
  102. i = MultiIndex(levels=[['qux', 'foo', 'baz', 'bar'],
  103. ['zenith', 'next', 'mom']],
  104. codes=[[0, 0, 0, 1, 1, 2, 2, 3, 3, 3],
  105. [0, 1, 2, 0, 1, 1, 2, 0, 1, 2]],
  106. names=['first', 'second'])
  107. assert i.is_monotonic_decreasing is True
  108. assert Index(i.values).is_monotonic_decreasing is True
  109. assert i._is_strictly_monotonic_decreasing is True
  110. assert Index(i.values)._is_strictly_monotonic_decreasing is True
  111. # mixed levels, hits the TypeError
  112. i = MultiIndex(
  113. levels=[[4, 3, 2, 1], ['nl0000301109', 'nl0000289965',
  114. 'nl0000289783', 'lu0197800237',
  115. 'gb00b03mlx29']],
  116. codes=[[0, 1, 1, 2, 2, 2, 3], [4, 2, 0, 0, 1, 3, -1]],
  117. names=['household_id', 'asset_id'])
  118. assert i.is_monotonic_decreasing is False
  119. assert i._is_strictly_monotonic_decreasing is False
  120. # empty
  121. i = MultiIndex.from_arrays([[], []])
  122. assert i.is_monotonic_decreasing is True
  123. assert Index(i.values).is_monotonic_decreasing is True
  124. assert i._is_strictly_monotonic_decreasing is True
  125. assert Index(i.values)._is_strictly_monotonic_decreasing is True
  126. def test_is_strictly_monotonic_increasing():
  127. idx = pd.MultiIndex(levels=[['bar', 'baz'], ['mom', 'next']],
  128. codes=[[0, 0, 1, 1], [0, 0, 0, 1]])
  129. assert idx.is_monotonic_increasing is True
  130. assert idx._is_strictly_monotonic_increasing is False
  131. def test_is_strictly_monotonic_decreasing():
  132. idx = pd.MultiIndex(levels=[['baz', 'bar'], ['next', 'mom']],
  133. codes=[[0, 0, 1, 1], [0, 0, 0, 1]])
  134. assert idx.is_monotonic_decreasing is True
  135. assert idx._is_strictly_monotonic_decreasing is False
  136. def test_searchsorted_monotonic(indices):
  137. # GH17271
  138. # not implemented for tuple searches in MultiIndex
  139. # or Intervals searches in IntervalIndex
  140. if isinstance(indices, (MultiIndex, IntervalIndex)):
  141. return
  142. # nothing to test if the index is empty
  143. if indices.empty:
  144. return
  145. value = indices[0]
  146. # determine the expected results (handle dupes for 'right')
  147. expected_left, expected_right = 0, (indices == value).argmin()
  148. if expected_right == 0:
  149. # all values are the same, expected_right should be length
  150. expected_right = len(indices)
  151. # test _searchsorted_monotonic in all cases
  152. # test searchsorted only for increasing
  153. if indices.is_monotonic_increasing:
  154. ssm_left = indices._searchsorted_monotonic(value, side='left')
  155. assert is_scalar(ssm_left)
  156. assert expected_left == ssm_left
  157. ssm_right = indices._searchsorted_monotonic(value, side='right')
  158. assert is_scalar(ssm_right)
  159. assert expected_right == ssm_right
  160. ss_left = indices.searchsorted(value, side='left')
  161. assert is_scalar(ss_left)
  162. assert expected_left == ss_left
  163. ss_right = indices.searchsorted(value, side='right')
  164. assert is_scalar(ss_right)
  165. assert expected_right == ss_right
  166. elif indices.is_monotonic_decreasing:
  167. ssm_left = indices._searchsorted_monotonic(value, side='left')
  168. assert is_scalar(ssm_left)
  169. assert expected_left == ssm_left
  170. ssm_right = indices._searchsorted_monotonic(value, side='right')
  171. assert is_scalar(ssm_right)
  172. assert expected_right == ssm_right
  173. else:
  174. # non-monotonic should raise.
  175. with pytest.raises(ValueError):
  176. indices._searchsorted_monotonic(value, side='left')