test_construction.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. from datetime import timedelta
  2. import numpy as np
  3. import pytest
  4. import pandas as pd
  5. from pandas import Timedelta, TimedeltaIndex, timedelta_range, to_timedelta
  6. from pandas.core.arrays import TimedeltaArray
  7. import pandas.util.testing as tm
  8. class TestTimedeltaIndex(object):
  9. def test_verify_integrity_deprecated(self):
  10. # GH#23919
  11. with tm.assert_produces_warning(FutureWarning):
  12. TimedeltaIndex(['1 Day'], verify_integrity=False)
  13. def test_range_kwargs_deprecated(self):
  14. # GH#23919
  15. with tm.assert_produces_warning(FutureWarning):
  16. TimedeltaIndex(start='1 Day', end='3 Days', freq='D')
  17. def test_int64_nocopy(self):
  18. # GH#23539 check that a copy isn't made when we pass int64 data
  19. # and copy=False
  20. arr = np.arange(10, dtype=np.int64)
  21. tdi = TimedeltaIndex(arr, copy=False)
  22. assert tdi._data._data.base is arr
  23. def test_infer_from_tdi(self):
  24. # GH#23539
  25. # fast-path for inferring a frequency if the passed data already
  26. # has one
  27. tdi = pd.timedelta_range('1 second', periods=10**7, freq='1s')
  28. result = pd.TimedeltaIndex(tdi, freq='infer')
  29. assert result.freq == tdi.freq
  30. # check that inferred_freq was not called by checking that the
  31. # value has not been cached
  32. assert "inferred_freq" not in getattr(result, "_cache", {})
  33. def test_infer_from_tdi_mismatch(self):
  34. # GH#23539
  35. # fast-path for invalidating a frequency if the passed data already
  36. # has one and it does not match the `freq` input
  37. tdi = pd.timedelta_range('1 second', periods=100, freq='1s')
  38. msg = ("Inferred frequency .* from passed values does "
  39. "not conform to passed frequency")
  40. with pytest.raises(ValueError, match=msg):
  41. TimedeltaIndex(tdi, freq='D')
  42. with pytest.raises(ValueError, match=msg):
  43. # GH#23789
  44. TimedeltaArray(tdi, freq='D')
  45. def test_dt64_data_invalid(self):
  46. # GH#23539
  47. # passing tz-aware DatetimeIndex raises, naive or ndarray[datetime64]
  48. # does not yet, but will in the future
  49. dti = pd.date_range('2016-01-01', periods=3)
  50. msg = "cannot be converted to timedelta64"
  51. with pytest.raises(TypeError, match=msg):
  52. TimedeltaIndex(dti.tz_localize('Europe/Brussels'))
  53. with tm.assert_produces_warning(FutureWarning):
  54. TimedeltaIndex(dti)
  55. with tm.assert_produces_warning(FutureWarning):
  56. TimedeltaIndex(np.asarray(dti))
  57. def test_float64_ns_rounded(self):
  58. # GH#23539 without specifying a unit, floats are regarded as nanos,
  59. # and fractional portions are truncated
  60. tdi = TimedeltaIndex([2.3, 9.7])
  61. expected = TimedeltaIndex([2, 9])
  62. tm.assert_index_equal(tdi, expected)
  63. # integral floats are non-lossy
  64. tdi = TimedeltaIndex([2.0, 9.0])
  65. expected = TimedeltaIndex([2, 9])
  66. tm.assert_index_equal(tdi, expected)
  67. # NaNs get converted to NaT
  68. tdi = TimedeltaIndex([2.0, np.nan])
  69. expected = TimedeltaIndex([pd.Timedelta(nanoseconds=2), pd.NaT])
  70. tm.assert_index_equal(tdi, expected)
  71. def test_float64_unit_conversion(self):
  72. # GH#23539
  73. tdi = TimedeltaIndex([1.5, 2.25], unit='D')
  74. expected = TimedeltaIndex([Timedelta(days=1.5), Timedelta(days=2.25)])
  75. tm.assert_index_equal(tdi, expected)
  76. def test_construction_base_constructor(self):
  77. arr = [pd.Timedelta('1 days'), pd.NaT, pd.Timedelta('3 days')]
  78. tm.assert_index_equal(pd.Index(arr), pd.TimedeltaIndex(arr))
  79. tm.assert_index_equal(pd.Index(np.array(arr)),
  80. pd.TimedeltaIndex(np.array(arr)))
  81. arr = [np.nan, pd.NaT, pd.Timedelta('1 days')]
  82. tm.assert_index_equal(pd.Index(arr), pd.TimedeltaIndex(arr))
  83. tm.assert_index_equal(pd.Index(np.array(arr)),
  84. pd.TimedeltaIndex(np.array(arr)))
  85. def test_constructor(self):
  86. expected = TimedeltaIndex(['1 days', '1 days 00:00:05', '2 days',
  87. '2 days 00:00:02', '0 days 00:00:03'])
  88. result = TimedeltaIndex(['1 days', '1 days, 00:00:05', np.timedelta64(
  89. 2, 'D'), timedelta(days=2, seconds=2), pd.offsets.Second(3)])
  90. tm.assert_index_equal(result, expected)
  91. # unicode
  92. result = TimedeltaIndex([u'1 days', '1 days, 00:00:05', np.timedelta64(
  93. 2, 'D'), timedelta(days=2, seconds=2), pd.offsets.Second(3)])
  94. expected = TimedeltaIndex(['0 days 00:00:00', '0 days 00:00:01',
  95. '0 days 00:00:02'])
  96. tm.assert_index_equal(TimedeltaIndex(range(3), unit='s'), expected)
  97. expected = TimedeltaIndex(['0 days 00:00:00', '0 days 00:00:05',
  98. '0 days 00:00:09'])
  99. tm.assert_index_equal(TimedeltaIndex([0, 5, 9], unit='s'), expected)
  100. expected = TimedeltaIndex(
  101. ['0 days 00:00:00.400', '0 days 00:00:00.450',
  102. '0 days 00:00:01.200'])
  103. tm.assert_index_equal(TimedeltaIndex([400, 450, 1200], unit='ms'),
  104. expected)
  105. def test_constructor_iso(self):
  106. # GH #21877
  107. expected = timedelta_range('1s', periods=9, freq='s')
  108. durations = ['P0DT0H0M{}S'.format(i) for i in range(1, 10)]
  109. result = to_timedelta(durations)
  110. tm.assert_index_equal(result, expected)
  111. def test_constructor_coverage(self):
  112. rng = timedelta_range('1 days', periods=10.5)
  113. exp = timedelta_range('1 days', periods=10)
  114. tm.assert_index_equal(rng, exp)
  115. msg = 'periods must be a number, got foo'
  116. with pytest.raises(TypeError, match=msg):
  117. timedelta_range(start='1 days', periods='foo', freq='D')
  118. with pytest.raises(ValueError):
  119. with tm.assert_produces_warning(FutureWarning):
  120. TimedeltaIndex(start='1 days', end='10 days')
  121. with pytest.raises(TypeError):
  122. TimedeltaIndex('1 days')
  123. # generator expression
  124. gen = (timedelta(i) for i in range(10))
  125. result = TimedeltaIndex(gen)
  126. expected = TimedeltaIndex([timedelta(i) for i in range(10)])
  127. tm.assert_index_equal(result, expected)
  128. # NumPy string array
  129. strings = np.array(['1 days', '2 days', '3 days'])
  130. result = TimedeltaIndex(strings)
  131. expected = to_timedelta([1, 2, 3], unit='d')
  132. tm.assert_index_equal(result, expected)
  133. from_ints = TimedeltaIndex(expected.asi8)
  134. tm.assert_index_equal(from_ints, expected)
  135. # non-conforming freq
  136. pytest.raises(ValueError, TimedeltaIndex,
  137. ['1 days', '2 days', '4 days'], freq='D')
  138. pytest.raises(ValueError, timedelta_range, periods=10, freq='D')
  139. def test_constructor_name(self):
  140. idx = timedelta_range(start='1 days', periods=1, freq='D', name='TEST')
  141. assert idx.name == 'TEST'
  142. # GH10025
  143. idx2 = TimedeltaIndex(idx, name='something else')
  144. assert idx2.name == 'something else'
  145. def test_constructor_no_precision_warns(self):
  146. # GH-24753, GH-24739
  147. expected = pd.TimedeltaIndex(['2000'], dtype='timedelta64[ns]')
  148. # we set the stacklevel for DatetimeIndex
  149. with tm.assert_produces_warning(FutureWarning):
  150. result = pd.TimedeltaIndex(['2000'], dtype='timedelta64')
  151. tm.assert_index_equal(result, expected)
  152. with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
  153. result = pd.Index(['2000'], dtype='timedelta64')
  154. tm.assert_index_equal(result, expected)
  155. def test_constructor_wrong_precision_raises(self):
  156. with pytest.raises(ValueError):
  157. pd.TimedeltaIndex(['2000'], dtype='timedelta64[us]')