test_datetime.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. from datetime import date
  2. import dateutil
  3. import numpy as np
  4. import pytest
  5. import pandas as pd
  6. from pandas import (
  7. DataFrame,
  8. DatetimeIndex,
  9. Index,
  10. Timestamp,
  11. date_range,
  12. offsets,
  13. )
  14. import pandas._testing as tm
  15. class TestDatetimeIndex:
  16. def test_sub_datetime_preserves_freq(self, tz_naive_fixture):
  17. # GH#48818
  18. dti = date_range("2016-01-01", periods=12, tz=tz_naive_fixture)
  19. res = dti - dti[0]
  20. expected = pd.timedelta_range("0 Days", "11 Days")
  21. tm.assert_index_equal(res, expected)
  22. assert res.freq == expected.freq
  23. @pytest.mark.xfail(
  24. reason="The inherited freq is incorrect bc dti.freq is incorrect "
  25. "https://github.com/pandas-dev/pandas/pull/48818/files#r982793461"
  26. )
  27. def test_sub_datetime_preserves_freq_across_dst(self):
  28. # GH#48818
  29. ts = Timestamp("2016-03-11", tz="US/Pacific")
  30. dti = date_range(ts, periods=4)
  31. res = dti - dti[0]
  32. expected = pd.TimedeltaIndex(
  33. [
  34. pd.Timedelta(days=0),
  35. pd.Timedelta(days=1),
  36. pd.Timedelta(days=2),
  37. pd.Timedelta(days=2, hours=23),
  38. ]
  39. )
  40. tm.assert_index_equal(res, expected)
  41. assert res.freq == expected.freq
  42. def test_time_overflow_for_32bit_machines(self):
  43. # GH8943. On some machines NumPy defaults to np.int32 (for example,
  44. # 32-bit Linux machines). In the function _generate_regular_range
  45. # found in tseries/index.py, `periods` gets multiplied by `strides`
  46. # (which has value 1e9) and since the max value for np.int32 is ~2e9,
  47. # and since those machines won't promote np.int32 to np.int64, we get
  48. # overflow.
  49. periods = np.int_(1000)
  50. idx1 = date_range(start="2000", periods=periods, freq="S")
  51. assert len(idx1) == periods
  52. idx2 = date_range(end="2000", periods=periods, freq="S")
  53. assert len(idx2) == periods
  54. def test_nat(self):
  55. assert DatetimeIndex([np.nan])[0] is pd.NaT
  56. def test_week_of_month_frequency(self):
  57. # GH 5348: "ValueError: Could not evaluate WOM-1SUN" shouldn't raise
  58. d1 = date(2002, 9, 1)
  59. d2 = date(2013, 10, 27)
  60. d3 = date(2012, 9, 30)
  61. idx1 = DatetimeIndex([d1, d2])
  62. idx2 = DatetimeIndex([d3])
  63. result_append = idx1.append(idx2)
  64. expected = DatetimeIndex([d1, d2, d3])
  65. tm.assert_index_equal(result_append, expected)
  66. result_union = idx1.union(idx2)
  67. expected = DatetimeIndex([d1, d3, d2])
  68. tm.assert_index_equal(result_union, expected)
  69. # GH 5115
  70. result = date_range("2013-1-1", periods=4, freq="WOM-1SAT")
  71. dates = ["2013-01-05", "2013-02-02", "2013-03-02", "2013-04-06"]
  72. expected = DatetimeIndex(dates, freq="WOM-1SAT")
  73. tm.assert_index_equal(result, expected)
  74. def test_append_nondatetimeindex(self):
  75. rng = date_range("1/1/2000", periods=10)
  76. idx = Index(["a", "b", "c", "d"])
  77. result = rng.append(idx)
  78. assert isinstance(result[0], Timestamp)
  79. def test_iteration_preserves_tz(self):
  80. # see gh-8890
  81. index = date_range("2012-01-01", periods=3, freq="H", tz="US/Eastern")
  82. for i, ts in enumerate(index):
  83. result = ts
  84. expected = index[i] # pylint: disable=unnecessary-list-index-lookup
  85. assert result == expected
  86. index = date_range(
  87. "2012-01-01", periods=3, freq="H", tz=dateutil.tz.tzoffset(None, -28800)
  88. )
  89. for i, ts in enumerate(index):
  90. result = ts
  91. expected = index[i] # pylint: disable=unnecessary-list-index-lookup
  92. assert result._repr_base == expected._repr_base
  93. assert result == expected
  94. # 9100
  95. index = DatetimeIndex(
  96. ["2014-12-01 03:32:39.987000-08:00", "2014-12-01 04:12:34.987000-08:00"]
  97. )
  98. for i, ts in enumerate(index):
  99. result = ts
  100. expected = index[i] # pylint: disable=unnecessary-list-index-lookup
  101. assert result._repr_base == expected._repr_base
  102. assert result == expected
  103. @pytest.mark.parametrize("periods", [0, 9999, 10000, 10001])
  104. def test_iteration_over_chunksize(self, periods):
  105. # GH21012
  106. index = date_range("2000-01-01 00:00:00", periods=periods, freq="min")
  107. num = 0
  108. for stamp in index:
  109. assert index[num] == stamp
  110. num += 1
  111. assert num == len(index)
  112. def test_misc_coverage(self):
  113. rng = date_range("1/1/2000", periods=5)
  114. result = rng.groupby(rng.day)
  115. assert isinstance(list(result.values())[0][0], Timestamp)
  116. def test_groupby_function_tuple_1677(self):
  117. df = DataFrame(np.random.rand(100), index=date_range("1/1/2000", periods=100))
  118. monthly_group = df.groupby(lambda x: (x.year, x.month))
  119. result = monthly_group.mean()
  120. assert isinstance(result.index[0], tuple)
  121. def assert_index_parameters(self, index):
  122. assert index.freq == "40960N"
  123. assert index.inferred_freq == "40960N"
  124. def test_ns_index(self):
  125. nsamples = 400
  126. ns = int(1e9 / 24414)
  127. dtstart = np.datetime64("2012-09-20T00:00:00")
  128. dt = dtstart + np.arange(nsamples) * np.timedelta64(ns, "ns")
  129. freq = ns * offsets.Nano()
  130. index = DatetimeIndex(dt, freq=freq, name="time")
  131. self.assert_index_parameters(index)
  132. new_index = date_range(start=index[0], end=index[-1], freq=index.freq)
  133. self.assert_index_parameters(new_index)
  134. def test_asarray_tz_naive(self):
  135. # This shouldn't produce a warning.
  136. idx = date_range("2000", periods=2)
  137. # M8[ns] by default
  138. result = np.asarray(idx)
  139. expected = np.array(["2000-01-01", "2000-01-02"], dtype="M8[ns]")
  140. tm.assert_numpy_array_equal(result, expected)
  141. # optionally, object
  142. result = np.asarray(idx, dtype=object)
  143. expected = np.array([Timestamp("2000-01-01"), Timestamp("2000-01-02")])
  144. tm.assert_numpy_array_equal(result, expected)
  145. def test_asarray_tz_aware(self):
  146. tz = "US/Central"
  147. idx = date_range("2000", periods=2, tz=tz)
  148. expected = np.array(["2000-01-01T06", "2000-01-02T06"], dtype="M8[ns]")
  149. result = np.asarray(idx, dtype="datetime64[ns]")
  150. tm.assert_numpy_array_equal(result, expected)
  151. # Old behavior with no warning
  152. result = np.asarray(idx, dtype="M8[ns]")
  153. tm.assert_numpy_array_equal(result, expected)
  154. # Future behavior with no warning
  155. expected = np.array(
  156. [Timestamp("2000-01-01", tz=tz), Timestamp("2000-01-02", tz=tz)]
  157. )
  158. result = np.asarray(idx, dtype=object)
  159. tm.assert_numpy_array_equal(result, expected)