test_between_time.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. from datetime import (
  2. datetime,
  3. time,
  4. )
  5. import numpy as np
  6. import pytest
  7. from pandas._libs.tslibs import timezones
  8. import pandas.util._test_decorators as td
  9. from pandas import (
  10. DataFrame,
  11. Series,
  12. date_range,
  13. )
  14. import pandas._testing as tm
  15. class TestBetweenTime:
  16. @td.skip_if_not_us_locale
  17. def test_between_time_formats(self, frame_or_series):
  18. # GH#11818
  19. rng = date_range("1/1/2000", "1/5/2000", freq="5min")
  20. ts = DataFrame(np.random.randn(len(rng), 2), index=rng)
  21. ts = tm.get_obj(ts, frame_or_series)
  22. strings = [
  23. ("2:00", "2:30"),
  24. ("0200", "0230"),
  25. ("2:00am", "2:30am"),
  26. ("0200am", "0230am"),
  27. ("2:00:00", "2:30:00"),
  28. ("020000", "023000"),
  29. ("2:00:00am", "2:30:00am"),
  30. ("020000am", "023000am"),
  31. ]
  32. expected_length = 28
  33. for time_string in strings:
  34. assert len(ts.between_time(*time_string)) == expected_length
  35. @pytest.mark.parametrize("tzstr", ["US/Eastern", "dateutil/US/Eastern"])
  36. def test_localized_between_time(self, tzstr, frame_or_series):
  37. tz = timezones.maybe_get_tz(tzstr)
  38. rng = date_range("4/16/2012", "5/1/2012", freq="H")
  39. ts = Series(np.random.randn(len(rng)), index=rng)
  40. if frame_or_series is DataFrame:
  41. ts = ts.to_frame()
  42. ts_local = ts.tz_localize(tzstr)
  43. t1, t2 = time(10, 0), time(11, 0)
  44. result = ts_local.between_time(t1, t2)
  45. expected = ts.between_time(t1, t2).tz_localize(tzstr)
  46. tm.assert_equal(result, expected)
  47. assert timezones.tz_compare(result.index.tz, tz)
  48. def test_between_time_types(self, frame_or_series):
  49. # GH11818
  50. rng = date_range("1/1/2000", "1/5/2000", freq="5min")
  51. obj = DataFrame({"A": 0}, index=rng)
  52. obj = tm.get_obj(obj, frame_or_series)
  53. msg = r"Cannot convert arg \[datetime\.datetime\(2010, 1, 2, 1, 0\)\] to a time"
  54. with pytest.raises(ValueError, match=msg):
  55. obj.between_time(datetime(2010, 1, 2, 1), datetime(2010, 1, 2, 5))
  56. def test_between_time(self, inclusive_endpoints_fixture, frame_or_series):
  57. rng = date_range("1/1/2000", "1/5/2000", freq="5min")
  58. ts = DataFrame(np.random.randn(len(rng), 2), index=rng)
  59. ts = tm.get_obj(ts, frame_or_series)
  60. stime = time(0, 0)
  61. etime = time(1, 0)
  62. inclusive = inclusive_endpoints_fixture
  63. filtered = ts.between_time(stime, etime, inclusive=inclusive)
  64. exp_len = 13 * 4 + 1
  65. if inclusive in ["right", "neither"]:
  66. exp_len -= 5
  67. if inclusive in ["left", "neither"]:
  68. exp_len -= 4
  69. assert len(filtered) == exp_len
  70. for rs in filtered.index:
  71. t = rs.time()
  72. if inclusive in ["left", "both"]:
  73. assert t >= stime
  74. else:
  75. assert t > stime
  76. if inclusive in ["right", "both"]:
  77. assert t <= etime
  78. else:
  79. assert t < etime
  80. result = ts.between_time("00:00", "01:00")
  81. expected = ts.between_time(stime, etime)
  82. tm.assert_equal(result, expected)
  83. # across midnight
  84. rng = date_range("1/1/2000", "1/5/2000", freq="5min")
  85. ts = DataFrame(np.random.randn(len(rng), 2), index=rng)
  86. ts = tm.get_obj(ts, frame_or_series)
  87. stime = time(22, 0)
  88. etime = time(9, 0)
  89. filtered = ts.between_time(stime, etime, inclusive=inclusive)
  90. exp_len = (12 * 11 + 1) * 4 + 1
  91. if inclusive in ["right", "neither"]:
  92. exp_len -= 4
  93. if inclusive in ["left", "neither"]:
  94. exp_len -= 4
  95. assert len(filtered) == exp_len
  96. for rs in filtered.index:
  97. t = rs.time()
  98. if inclusive in ["left", "both"]:
  99. assert (t >= stime) or (t <= etime)
  100. else:
  101. assert (t > stime) or (t <= etime)
  102. if inclusive in ["right", "both"]:
  103. assert (t <= etime) or (t >= stime)
  104. else:
  105. assert (t < etime) or (t >= stime)
  106. def test_between_time_raises(self, frame_or_series):
  107. # GH#20725
  108. obj = DataFrame([[1, 2, 3], [4, 5, 6]])
  109. obj = tm.get_obj(obj, frame_or_series)
  110. msg = "Index must be DatetimeIndex"
  111. with pytest.raises(TypeError, match=msg): # index is not a DatetimeIndex
  112. obj.between_time(start_time="00:00", end_time="12:00")
  113. def test_between_time_axis(self, frame_or_series):
  114. # GH#8839
  115. rng = date_range("1/1/2000", periods=100, freq="10min")
  116. ts = Series(np.random.randn(len(rng)), index=rng)
  117. if frame_or_series is DataFrame:
  118. ts = ts.to_frame()
  119. stime, etime = ("08:00:00", "09:00:00")
  120. expected_length = 7
  121. assert len(ts.between_time(stime, etime)) == expected_length
  122. assert len(ts.between_time(stime, etime, axis=0)) == expected_length
  123. msg = f"No axis named {ts.ndim} for object type {type(ts).__name__}"
  124. with pytest.raises(ValueError, match=msg):
  125. ts.between_time(stime, etime, axis=ts.ndim)
  126. def test_between_time_axis_aliases(self, axis):
  127. # GH#8839
  128. rng = date_range("1/1/2000", periods=100, freq="10min")
  129. ts = DataFrame(np.random.randn(len(rng), len(rng)))
  130. stime, etime = ("08:00:00", "09:00:00")
  131. exp_len = 7
  132. if axis in ["index", 0]:
  133. ts.index = rng
  134. assert len(ts.between_time(stime, etime)) == exp_len
  135. assert len(ts.between_time(stime, etime, axis=0)) == exp_len
  136. if axis in ["columns", 1]:
  137. ts.columns = rng
  138. selected = ts.between_time(stime, etime, axis=1).columns
  139. assert len(selected) == exp_len
  140. def test_between_time_axis_raises(self, axis):
  141. # issue 8839
  142. rng = date_range("1/1/2000", periods=100, freq="10min")
  143. mask = np.arange(0, len(rng))
  144. rand_data = np.random.randn(len(rng), len(rng))
  145. ts = DataFrame(rand_data, index=rng, columns=rng)
  146. stime, etime = ("08:00:00", "09:00:00")
  147. msg = "Index must be DatetimeIndex"
  148. if axis in ["columns", 1]:
  149. ts.index = mask
  150. with pytest.raises(TypeError, match=msg):
  151. ts.between_time(stime, etime)
  152. with pytest.raises(TypeError, match=msg):
  153. ts.between_time(stime, etime, axis=0)
  154. if axis in ["index", 0]:
  155. ts.columns = mask
  156. with pytest.raises(TypeError, match=msg):
  157. ts.between_time(stime, etime, axis=1)
  158. def test_between_time_datetimeindex(self):
  159. index = date_range("2012-01-01", "2012-01-05", freq="30min")
  160. df = DataFrame(np.random.randn(len(index), 5), index=index)
  161. bkey = slice(time(13, 0, 0), time(14, 0, 0))
  162. binds = [26, 27, 28, 74, 75, 76, 122, 123, 124, 170, 171, 172]
  163. result = df.between_time(bkey.start, bkey.stop)
  164. expected = df.loc[bkey]
  165. expected2 = df.iloc[binds]
  166. tm.assert_frame_equal(result, expected)
  167. tm.assert_frame_equal(result, expected2)
  168. assert len(result) == 12
  169. def test_between_time_incorrect_arg_inclusive(self):
  170. # GH40245
  171. rng = date_range("1/1/2000", "1/5/2000", freq="5min")
  172. ts = DataFrame(np.random.randn(len(rng), 2), index=rng)
  173. stime = time(0, 0)
  174. etime = time(1, 0)
  175. inclusive = "bad_string"
  176. msg = "Inclusive has to be either 'both', 'neither', 'left' or 'right'"
  177. with pytest.raises(ValueError, match=msg):
  178. ts.between_time(stime, etime, inclusive=inclusive)