test_libalgos.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. from datetime import datetime
  2. from itertools import permutations
  3. import numpy as np
  4. from pandas._libs import algos as libalgos
  5. import pandas._testing as tm
  6. def test_ensure_platform_int():
  7. arr = np.arange(100, dtype=np.intp)
  8. result = libalgos.ensure_platform_int(arr)
  9. assert result is arr
  10. def test_is_lexsorted():
  11. failure = [
  12. np.array(
  13. ([3] * 32) + ([2] * 32) + ([1] * 32) + ([0] * 32),
  14. dtype="int64",
  15. ),
  16. np.array(
  17. list(range(31))[::-1] * 4,
  18. dtype="int64",
  19. ),
  20. ]
  21. assert not libalgos.is_lexsorted(failure)
  22. def test_groupsort_indexer():
  23. a = np.random.default_rng(2).integers(0, 1000, 100).astype(np.intp)
  24. b = np.random.default_rng(2).integers(0, 1000, 100).astype(np.intp)
  25. result = libalgos.groupsort_indexer(a, 1000)[0]
  26. # need to use a stable sort
  27. # np.argsort returns int, groupsort_indexer
  28. # always returns intp
  29. expected = np.argsort(a, kind="mergesort")
  30. expected = expected.astype(np.intp)
  31. tm.assert_numpy_array_equal(result, expected)
  32. # compare with lexsort
  33. # np.lexsort returns int, groupsort_indexer
  34. # always returns intp
  35. key = a * 1000 + b
  36. result = libalgos.groupsort_indexer(key, 1000000)[0]
  37. expected = np.lexsort((b, a))
  38. expected = expected.astype(np.intp)
  39. tm.assert_numpy_array_equal(result, expected)
  40. class TestPadBackfill:
  41. def test_backfill(self):
  42. old = np.array([1, 5, 10], dtype=np.int64)
  43. new = np.array(list(range(12)), dtype=np.int64)
  44. filler = libalgos.backfill["int64_t"](old, new)
  45. expect_filler = np.array([0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1], dtype=np.intp)
  46. tm.assert_numpy_array_equal(filler, expect_filler)
  47. # corner case
  48. old = np.array([1, 4], dtype=np.int64)
  49. new = np.array(list(range(5, 10)), dtype=np.int64)
  50. filler = libalgos.backfill["int64_t"](old, new)
  51. expect_filler = np.array([-1, -1, -1, -1, -1], dtype=np.intp)
  52. tm.assert_numpy_array_equal(filler, expect_filler)
  53. def test_pad(self):
  54. old = np.array([1, 5, 10], dtype=np.int64)
  55. new = np.array(list(range(12)), dtype=np.int64)
  56. filler = libalgos.pad["int64_t"](old, new)
  57. expect_filler = np.array([-1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2], dtype=np.intp)
  58. tm.assert_numpy_array_equal(filler, expect_filler)
  59. # corner case
  60. old = np.array([5, 10], dtype=np.int64)
  61. new = np.arange(5, dtype=np.int64)
  62. filler = libalgos.pad["int64_t"](old, new)
  63. expect_filler = np.array([-1, -1, -1, -1, -1], dtype=np.intp)
  64. tm.assert_numpy_array_equal(filler, expect_filler)
  65. def test_pad_backfill_object_segfault(self):
  66. old = np.array([], dtype="O")
  67. new = np.array([datetime(2010, 12, 31)], dtype="O")
  68. result = libalgos.pad["object"](old, new)
  69. expected = np.array([-1], dtype=np.intp)
  70. tm.assert_numpy_array_equal(result, expected)
  71. result = libalgos.pad["object"](new, old)
  72. expected = np.array([], dtype=np.intp)
  73. tm.assert_numpy_array_equal(result, expected)
  74. result = libalgos.backfill["object"](old, new)
  75. expected = np.array([-1], dtype=np.intp)
  76. tm.assert_numpy_array_equal(result, expected)
  77. result = libalgos.backfill["object"](new, old)
  78. expected = np.array([], dtype=np.intp)
  79. tm.assert_numpy_array_equal(result, expected)
  80. class TestInfinity:
  81. def test_infinity_sort(self):
  82. # GH#13445
  83. # numpy's argsort can be unhappy if something is less than
  84. # itself. Instead, let's give our infinities a self-consistent
  85. # ordering, but outside the float extended real line.
  86. Inf = libalgos.Infinity()
  87. NegInf = libalgos.NegInfinity()
  88. ref_nums = [NegInf, float("-inf"), -1e100, 0, 1e100, float("inf"), Inf]
  89. assert all(Inf >= x for x in ref_nums)
  90. assert all(Inf > x or x is Inf for x in ref_nums)
  91. assert Inf >= Inf and Inf == Inf
  92. assert not Inf < Inf and not Inf > Inf
  93. assert libalgos.Infinity() == libalgos.Infinity()
  94. assert not libalgos.Infinity() != libalgos.Infinity()
  95. assert all(NegInf <= x for x in ref_nums)
  96. assert all(NegInf < x or x is NegInf for x in ref_nums)
  97. assert NegInf <= NegInf and NegInf == NegInf
  98. assert not NegInf < NegInf and not NegInf > NegInf
  99. assert libalgos.NegInfinity() == libalgos.NegInfinity()
  100. assert not libalgos.NegInfinity() != libalgos.NegInfinity()
  101. for perm in permutations(ref_nums):
  102. assert sorted(perm) == ref_nums
  103. # smoke tests
  104. np.array([libalgos.Infinity()] * 32).argsort()
  105. np.array([libalgos.NegInfinity()] * 32).argsort()
  106. def test_infinity_against_nan(self):
  107. Inf = libalgos.Infinity()
  108. NegInf = libalgos.NegInfinity()
  109. assert not Inf > np.nan
  110. assert not Inf >= np.nan
  111. assert not Inf < np.nan
  112. assert not Inf <= np.nan
  113. assert not Inf == np.nan
  114. assert Inf != np.nan
  115. assert not NegInf > np.nan
  116. assert not NegInf >= np.nan
  117. assert not NegInf < np.nan
  118. assert not NegInf <= np.nan
  119. assert not NegInf == np.nan
  120. assert NegInf != np.nan