test_asfreq.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. from datetime import datetime
  2. import numpy as np
  3. import pytest
  4. from pandas._libs.tslibs.offsets import MonthEnd
  5. from pandas import (
  6. DataFrame,
  7. DatetimeIndex,
  8. Series,
  9. date_range,
  10. period_range,
  11. to_datetime,
  12. )
  13. import pandas._testing as tm
  14. from pandas.tseries import offsets
  15. class TestAsFreq:
  16. @pytest.fixture(params=["s", "ms", "us", "ns"])
  17. def unit(self, request):
  18. return request.param
  19. def test_asfreq2(self, frame_or_series):
  20. ts = frame_or_series(
  21. [0.0, 1.0, 2.0],
  22. index=DatetimeIndex(
  23. [
  24. datetime(2009, 10, 30),
  25. datetime(2009, 11, 30),
  26. datetime(2009, 12, 31),
  27. ],
  28. dtype="M8[ns]",
  29. freq="BME",
  30. ),
  31. )
  32. daily_ts = ts.asfreq("B")
  33. monthly_ts = daily_ts.asfreq("BME")
  34. tm.assert_equal(monthly_ts, ts)
  35. daily_ts = ts.asfreq("B", method="pad")
  36. monthly_ts = daily_ts.asfreq("BME")
  37. tm.assert_equal(monthly_ts, ts)
  38. daily_ts = ts.asfreq(offsets.BDay())
  39. monthly_ts = daily_ts.asfreq(offsets.BMonthEnd())
  40. tm.assert_equal(monthly_ts, ts)
  41. result = ts[:0].asfreq("ME")
  42. assert len(result) == 0
  43. assert result is not ts
  44. if frame_or_series is Series:
  45. daily_ts = ts.asfreq("D", fill_value=-1)
  46. result = daily_ts.value_counts().sort_index()
  47. expected = Series(
  48. [60, 1, 1, 1], index=[-1.0, 2.0, 1.0, 0.0], name="count"
  49. ).sort_index()
  50. tm.assert_series_equal(result, expected)
  51. def test_asfreq_datetimeindex_empty(self, frame_or_series):
  52. # GH#14320
  53. index = DatetimeIndex(["2016-09-29 11:00"])
  54. expected = frame_or_series(index=index, dtype=object).asfreq("h")
  55. result = frame_or_series([3], index=index.copy()).asfreq("h")
  56. tm.assert_index_equal(expected.index, result.index)
  57. @pytest.mark.parametrize("tz", ["US/Eastern", "dateutil/US/Eastern"])
  58. def test_tz_aware_asfreq_smoke(self, tz, frame_or_series):
  59. dr = date_range("2011-12-01", "2012-07-20", freq="D", tz=tz)
  60. obj = frame_or_series(
  61. np.random.default_rng(2).standard_normal(len(dr)), index=dr
  62. )
  63. # it works!
  64. obj.asfreq("min")
  65. def test_asfreq_normalize(self, frame_or_series):
  66. rng = date_range("1/1/2000 09:30", periods=20)
  67. norm = date_range("1/1/2000", periods=20)
  68. vals = np.random.default_rng(2).standard_normal((20, 3))
  69. obj = DataFrame(vals, index=rng)
  70. expected = DataFrame(vals, index=norm)
  71. if frame_or_series is Series:
  72. obj = obj[0]
  73. expected = expected[0]
  74. result = obj.asfreq("D", normalize=True)
  75. tm.assert_equal(result, expected)
  76. def test_asfreq_keep_index_name(self, frame_or_series):
  77. # GH#9854
  78. index_name = "bar"
  79. index = date_range("20130101", periods=20, name=index_name)
  80. obj = DataFrame(list(range(20)), columns=["foo"], index=index)
  81. obj = tm.get_obj(obj, frame_or_series)
  82. assert index_name == obj.index.name
  83. assert index_name == obj.asfreq("10D").index.name
  84. def test_asfreq_ts(self, frame_or_series):
  85. index = period_range(freq="Y", start="1/1/2001", end="12/31/2010")
  86. obj = DataFrame(
  87. np.random.default_rng(2).standard_normal((len(index), 3)), index=index
  88. )
  89. obj = tm.get_obj(obj, frame_or_series)
  90. result = obj.asfreq("D", how="end")
  91. exp_index = index.asfreq("D", how="end")
  92. assert len(result) == len(obj)
  93. tm.assert_index_equal(result.index, exp_index)
  94. result = obj.asfreq("D", how="start")
  95. exp_index = index.asfreq("D", how="start")
  96. assert len(result) == len(obj)
  97. tm.assert_index_equal(result.index, exp_index)
  98. def test_asfreq_resample_set_correct_freq(self, frame_or_series):
  99. # GH#5613
  100. # we test if .asfreq() and .resample() set the correct value for .freq
  101. dti = to_datetime(["2012-01-01", "2012-01-02", "2012-01-03"])
  102. obj = DataFrame({"col": [1, 2, 3]}, index=dti)
  103. obj = tm.get_obj(obj, frame_or_series)
  104. # testing the settings before calling .asfreq() and .resample()
  105. assert obj.index.freq is None
  106. assert obj.index.inferred_freq == "D"
  107. # does .asfreq() set .freq correctly?
  108. assert obj.asfreq("D").index.freq == "D"
  109. # does .resample() set .freq correctly?
  110. assert obj.resample("D").asfreq().index.freq == "D"
  111. def test_asfreq_empty(self, datetime_frame):
  112. # test does not blow up on length-0 DataFrame
  113. zero_length = datetime_frame.reindex([])
  114. result = zero_length.asfreq("BME")
  115. assert result is not zero_length
  116. def test_asfreq(self, datetime_frame):
  117. offset_monthly = datetime_frame.asfreq(offsets.BMonthEnd())
  118. rule_monthly = datetime_frame.asfreq("BME")
  119. tm.assert_frame_equal(offset_monthly, rule_monthly)
  120. rule_monthly.asfreq("B", method="pad")
  121. # TODO: actually check that this worked.
  122. # don't forget!
  123. rule_monthly.asfreq("B", method="pad")
  124. def test_asfreq_datetimeindex(self):
  125. df = DataFrame(
  126. {"A": [1, 2, 3]},
  127. index=[datetime(2011, 11, 1), datetime(2011, 11, 2), datetime(2011, 11, 3)],
  128. )
  129. df = df.asfreq("B")
  130. assert isinstance(df.index, DatetimeIndex)
  131. ts = df["A"].asfreq("B")
  132. assert isinstance(ts.index, DatetimeIndex)
  133. def test_asfreq_fillvalue(self):
  134. # test for fill value during upsampling, related to issue 3715
  135. # setup
  136. rng = date_range("1/1/2016", periods=10, freq="2s")
  137. # Explicit cast to 'float' to avoid implicit cast when setting None
  138. ts = Series(np.arange(len(rng)), index=rng, dtype="float")
  139. df = DataFrame({"one": ts})
  140. # insert pre-existing missing value
  141. df.loc["2016-01-01 00:00:08", "one"] = None
  142. actual_df = df.asfreq(freq="1s", fill_value=9.0)
  143. expected_df = df.asfreq(freq="1s").fillna(9.0)
  144. expected_df.loc["2016-01-01 00:00:08", "one"] = None
  145. tm.assert_frame_equal(expected_df, actual_df)
  146. expected_series = ts.asfreq(freq="1s").fillna(9.0)
  147. actual_series = ts.asfreq(freq="1s", fill_value=9.0)
  148. tm.assert_series_equal(expected_series, actual_series)
  149. def test_asfreq_with_date_object_index(self, frame_or_series):
  150. rng = date_range("1/1/2000", periods=20)
  151. ts = frame_or_series(np.random.default_rng(2).standard_normal(20), index=rng)
  152. ts2 = ts.copy()
  153. ts2.index = [x.date() for x in ts2.index]
  154. result = ts2.asfreq("4h", method="ffill")
  155. expected = ts.asfreq("4h", method="ffill")
  156. tm.assert_equal(result, expected)
  157. def test_asfreq_with_unsorted_index(self, frame_or_series):
  158. # GH#39805
  159. # Test that rows are not dropped when the datetime index is out of order
  160. index = to_datetime(["2021-01-04", "2021-01-02", "2021-01-03", "2021-01-01"])
  161. result = frame_or_series(range(4), index=index)
  162. expected = result.reindex(sorted(index))
  163. expected.index = expected.index._with_freq("infer")
  164. result = result.asfreq("D")
  165. tm.assert_equal(result, expected)
  166. def test_asfreq_after_normalize(self, unit):
  167. # https://github.com/pandas-dev/pandas/issues/50727
  168. result = DatetimeIndex(
  169. date_range("2000", periods=2).as_unit(unit).normalize(), freq="D"
  170. )
  171. expected = DatetimeIndex(["2000-01-01", "2000-01-02"], freq="D").as_unit(unit)
  172. tm.assert_index_equal(result, expected)
  173. @pytest.mark.parametrize(
  174. "freq, freq_half",
  175. [
  176. ("2ME", "ME"),
  177. (MonthEnd(2), MonthEnd(1)),
  178. ],
  179. )
  180. def test_asfreq_2ME(self, freq, freq_half):
  181. index = date_range("1/1/2000", periods=6, freq=freq_half)
  182. df = DataFrame({"s": Series([0.0, 1.0, 2.0, 3.0, 4.0, 5.0], index=index)})
  183. expected = df.asfreq(freq=freq)
  184. index = date_range("1/1/2000", periods=3, freq=freq)
  185. result = DataFrame({"s": Series([0.0, 2.0, 4.0], index=index)})
  186. tm.assert_frame_equal(result, expected)
  187. @pytest.mark.parametrize(
  188. "freq, freq_depr",
  189. [
  190. ("2ME", "2M"),
  191. ("2QE", "2Q"),
  192. ("2QE-SEP", "2Q-SEP"),
  193. ("1BQE", "1BQ"),
  194. ("2BQE-SEP", "2BQ-SEP"),
  195. ("1YE", "1Y"),
  196. ("2YE-MAR", "2Y-MAR"),
  197. ("1YE", "1A"),
  198. ("2YE-MAR", "2A-MAR"),
  199. ("2BYE-MAR", "2BA-MAR"),
  200. ],
  201. )
  202. def test_asfreq_frequency_M_Q_Y_A_deprecated(self, freq, freq_depr):
  203. # GH#9586, #55978
  204. depr_msg = f"'{freq_depr[1:]}' is deprecated and will be removed "
  205. f"in a future version, please use '{freq[1:]}' instead."
  206. index = date_range("1/1/2000", periods=4, freq=f"{freq[1:]}")
  207. df = DataFrame({"s": Series([0.0, 1.0, 2.0, 3.0], index=index)})
  208. expected = df.asfreq(freq=freq)
  209. with tm.assert_produces_warning(FutureWarning, match=depr_msg):
  210. result = df.asfreq(freq=freq_depr)
  211. tm.assert_frame_equal(result, expected)