test_period.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import numpy as np
  2. import pytest
  3. from pandas._libs.tslibs import (
  4. iNaT,
  5. to_offset,
  6. )
  7. from pandas._libs.tslibs.period import (
  8. extract_ordinals,
  9. get_period_field_arr,
  10. period_asfreq,
  11. period_ordinal,
  12. )
  13. import pandas._testing as tm
  14. def get_freq_code(freqstr: str) -> int:
  15. off = to_offset(freqstr, is_period=True)
  16. # error: "BaseOffset" has no attribute "_period_dtype_code"
  17. code = off._period_dtype_code # type: ignore[attr-defined]
  18. return code
  19. @pytest.mark.parametrize(
  20. "freq1,freq2,expected",
  21. [
  22. ("D", "h", 24),
  23. ("D", "min", 1440),
  24. ("D", "s", 86400),
  25. ("D", "ms", 86400000),
  26. ("D", "us", 86400000000),
  27. ("D", "ns", 86400000000000),
  28. ("h", "min", 60),
  29. ("h", "s", 3600),
  30. ("h", "ms", 3600000),
  31. ("h", "us", 3600000000),
  32. ("h", "ns", 3600000000000),
  33. ("min", "s", 60),
  34. ("min", "ms", 60000),
  35. ("min", "us", 60000000),
  36. ("min", "ns", 60000000000),
  37. ("s", "ms", 1000),
  38. ("s", "us", 1000000),
  39. ("s", "ns", 1000000000),
  40. ("ms", "us", 1000),
  41. ("ms", "ns", 1000000),
  42. ("us", "ns", 1000),
  43. ],
  44. )
  45. def test_intra_day_conversion_factors(freq1, freq2, expected):
  46. assert (
  47. period_asfreq(1, get_freq_code(freq1), get_freq_code(freq2), False) == expected
  48. )
  49. @pytest.mark.parametrize(
  50. "freq,expected", [("Y", 0), ("M", 0), ("W", 1), ("D", 0), ("B", 0)]
  51. )
  52. def test_period_ordinal_start_values(freq, expected):
  53. # information for Jan. 1, 1970.
  54. assert period_ordinal(1970, 1, 1, 0, 0, 0, 0, 0, get_freq_code(freq)) == expected
  55. @pytest.mark.parametrize(
  56. "dt,expected",
  57. [
  58. ((1970, 1, 4, 0, 0, 0, 0, 0), 1),
  59. ((1970, 1, 5, 0, 0, 0, 0, 0), 2),
  60. ((2013, 10, 6, 0, 0, 0, 0, 0), 2284),
  61. ((2013, 10, 7, 0, 0, 0, 0, 0), 2285),
  62. ],
  63. )
  64. def test_period_ordinal_week(dt, expected):
  65. args = dt + (get_freq_code("W"),)
  66. assert period_ordinal(*args) == expected
  67. @pytest.mark.parametrize(
  68. "day,expected",
  69. [
  70. # Thursday (Oct. 3, 2013).
  71. (3, 11415),
  72. # Friday (Oct. 4, 2013).
  73. (4, 11416),
  74. # Saturday (Oct. 5, 2013).
  75. (5, 11417),
  76. # Sunday (Oct. 6, 2013).
  77. (6, 11417),
  78. # Monday (Oct. 7, 2013).
  79. (7, 11417),
  80. # Tuesday (Oct. 8, 2013).
  81. (8, 11418),
  82. ],
  83. )
  84. def test_period_ordinal_business_day(day, expected):
  85. # 5000 is PeriodDtypeCode for BusinessDay
  86. args = (2013, 10, day, 0, 0, 0, 0, 0, 5000)
  87. assert period_ordinal(*args) == expected
  88. class TestExtractOrdinals:
  89. def test_extract_ordinals_raises(self):
  90. # with non-object, make sure we raise TypeError, not segfault
  91. arr = np.arange(5)
  92. freq = to_offset("D")
  93. with pytest.raises(TypeError, match="values must be object-dtype"):
  94. extract_ordinals(arr, freq)
  95. def test_extract_ordinals_2d(self):
  96. freq = to_offset("D")
  97. arr = np.empty(10, dtype=object)
  98. arr[:] = iNaT
  99. res = extract_ordinals(arr, freq)
  100. res2 = extract_ordinals(arr.reshape(5, 2), freq)
  101. tm.assert_numpy_array_equal(res, res2.reshape(-1))
  102. def test_get_period_field_array_raises_on_out_of_range():
  103. msg = "Buffer dtype mismatch, expected 'const int64_t' but got 'double'"
  104. with pytest.raises(ValueError, match=msg):
  105. get_period_field_arr(-1, np.empty(1), 0)