1.. _timedeltas: 2 3{{ header }} 4 5.. _timedeltas.timedeltas: 6 7*********** 8Time deltas 9*********** 10 11Timedeltas are differences in times, expressed in difference units, e.g. days, hours, minutes, 12seconds. They can be both positive and negative. 13 14``Timedelta`` is a subclass of ``datetime.timedelta``, and behaves in a similar manner, 15but allows compatibility with ``np.timedelta64`` types as well as a host of custom representation, 16parsing, and attributes. 17 18Parsing 19------- 20 21You can construct a ``Timedelta`` scalar through various arguments, including `ISO 8601 Duration`_ strings. 22 23.. ipython:: python 24 25 import datetime 26 27 # strings 28 pd.Timedelta("1 days") 29 pd.Timedelta("1 days 00:00:00") 30 pd.Timedelta("1 days 2 hours") 31 pd.Timedelta("-1 days 2 min 3us") 32 33 # like datetime.timedelta 34 # note: these MUST be specified as keyword arguments 35 pd.Timedelta(days=1, seconds=1) 36 37 # integers with a unit 38 pd.Timedelta(1, unit="d") 39 40 # from a datetime.timedelta/np.timedelta64 41 pd.Timedelta(datetime.timedelta(days=1, seconds=1)) 42 pd.Timedelta(np.timedelta64(1, "ms")) 43 44 # negative Timedeltas have this string repr 45 # to be more consistent with datetime.timedelta conventions 46 pd.Timedelta("-1us") 47 48 # a NaT 49 pd.Timedelta("nan") 50 pd.Timedelta("nat") 51 52 # ISO 8601 Duration strings 53 pd.Timedelta("P0DT0H1M0S") 54 pd.Timedelta("P0DT0H0M0.000000123S") 55 56:ref:`DateOffsets<timeseries.offsets>` (``Day, Hour, Minute, Second, Milli, Micro, Nano``) can also be used in construction. 57 58.. ipython:: python 59 60 pd.Timedelta(pd.offsets.Second(2)) 61 62Further, operations among the scalars yield another scalar ``Timedelta``. 63 64.. ipython:: python 65 66 pd.Timedelta(pd.offsets.Day(2)) + pd.Timedelta(pd.offsets.Second(2)) + pd.Timedelta( 67 "00:00:00.000123" 68 ) 69 70to_timedelta 71~~~~~~~~~~~~ 72 73Using the top-level ``pd.to_timedelta``, you can convert a scalar, array, list, 74or Series from a recognized timedelta format / value into a ``Timedelta`` type. 75It will construct Series if the input is a Series, a scalar if the input is 76scalar-like, otherwise it will output a ``TimedeltaIndex``. 77 78You can parse a single string to a Timedelta: 79 80.. ipython:: python 81 82 pd.to_timedelta("1 days 06:05:01.00003") 83 pd.to_timedelta("15.5us") 84 85or a list/array of strings: 86 87.. ipython:: python 88 89 pd.to_timedelta(["1 days 06:05:01.00003", "15.5us", "nan"]) 90 91The ``unit`` keyword argument specifies the unit of the Timedelta: 92 93.. ipython:: python 94 95 pd.to_timedelta(np.arange(5), unit="s") 96 pd.to_timedelta(np.arange(5), unit="d") 97 98.. _timedeltas.limitations: 99 100Timedelta limitations 101~~~~~~~~~~~~~~~~~~~~~ 102 103pandas represents ``Timedeltas`` in nanosecond resolution using 10464 bit integers. As such, the 64 bit integer limits determine 105the ``Timedelta`` limits. 106 107.. ipython:: python 108 109 pd.Timedelta.min 110 pd.Timedelta.max 111 112.. _timedeltas.operations: 113 114Operations 115---------- 116 117You can operate on Series/DataFrames and construct ``timedelta64[ns]`` Series through 118subtraction operations on ``datetime64[ns]`` Series, or ``Timestamps``. 119 120.. ipython:: python 121 122 s = pd.Series(pd.date_range("2012-1-1", periods=3, freq="D")) 123 td = pd.Series([pd.Timedelta(days=i) for i in range(3)]) 124 df = pd.DataFrame({"A": s, "B": td}) 125 df 126 df["C"] = df["A"] + df["B"] 127 df 128 df.dtypes 129 130 s - s.max() 131 s - datetime.datetime(2011, 1, 1, 3, 5) 132 s + datetime.timedelta(minutes=5) 133 s + pd.offsets.Minute(5) 134 s + pd.offsets.Minute(5) + pd.offsets.Milli(5) 135 136Operations with scalars from a ``timedelta64[ns]`` series: 137 138.. ipython:: python 139 140 y = s - s[0] 141 y 142 143Series of timedeltas with ``NaT`` values are supported: 144 145.. ipython:: python 146 147 y = s - s.shift() 148 y 149 150Elements can be set to ``NaT`` using ``np.nan`` analogously to datetimes: 151 152.. ipython:: python 153 154 y[1] = np.nan 155 y 156 157Operands can also appear in a reversed order (a singular object operated with a Series): 158 159.. ipython:: python 160 161 s.max() - s 162 datetime.datetime(2011, 1, 1, 3, 5) - s 163 datetime.timedelta(minutes=5) + s 164 165``min, max`` and the corresponding ``idxmin, idxmax`` operations are supported on frames: 166 167.. ipython:: python 168 169 A = s - pd.Timestamp("20120101") - pd.Timedelta("00:05:05") 170 B = s - pd.Series(pd.date_range("2012-1-2", periods=3, freq="D")) 171 172 df = pd.DataFrame({"A": A, "B": B}) 173 df 174 175 df.min() 176 df.min(axis=1) 177 178 df.idxmin() 179 df.idxmax() 180 181``min, max, idxmin, idxmax`` operations are supported on Series as well. A scalar result will be a ``Timedelta``. 182 183.. ipython:: python 184 185 df.min().max() 186 df.min(axis=1).min() 187 188 df.min().idxmax() 189 df.min(axis=1).idxmin() 190 191You can fillna on timedeltas, passing a timedelta to get a particular value. 192 193.. ipython:: python 194 195 y.fillna(pd.Timedelta(0)) 196 y.fillna(pd.Timedelta(10, unit="s")) 197 y.fillna(pd.Timedelta("-1 days, 00:00:05")) 198 199You can also negate, multiply and use ``abs`` on ``Timedeltas``: 200 201.. ipython:: python 202 203 td1 = pd.Timedelta("-1 days 2 hours 3 seconds") 204 td1 205 -1 * td1 206 -td1 207 abs(td1) 208 209.. _timedeltas.timedeltas_reductions: 210 211Reductions 212---------- 213 214Numeric reduction operation for ``timedelta64[ns]`` will return ``Timedelta`` objects. As usual 215``NaT`` are skipped during evaluation. 216 217.. ipython:: python 218 219 y2 = pd.Series( 220 pd.to_timedelta(["-1 days +00:00:05", "nat", "-1 days +00:00:05", "1 days"]) 221 ) 222 y2 223 y2.mean() 224 y2.median() 225 y2.quantile(0.1) 226 y2.sum() 227 228.. _timedeltas.timedeltas_convert: 229 230Frequency conversion 231-------------------- 232 233Timedelta Series, ``TimedeltaIndex``, and ``Timedelta`` scalars can be converted to other 'frequencies' by dividing by another timedelta, 234or by astyping to a specific timedelta type. These operations yield Series and propagate ``NaT`` -> ``nan``. 235Note that division by the NumPy scalar is true division, while astyping is equivalent of floor division. 236 237.. ipython:: python 238 239 december = pd.Series(pd.date_range("20121201", periods=4)) 240 january = pd.Series(pd.date_range("20130101", periods=4)) 241 td = january - december 242 243 td[2] += datetime.timedelta(minutes=5, seconds=3) 244 td[3] = np.nan 245 td 246 247 # to days 248 td / np.timedelta64(1, "D") 249 td.astype("timedelta64[D]") 250 251 # to seconds 252 td / np.timedelta64(1, "s") 253 td.astype("timedelta64[s]") 254 255 # to months (these are constant months) 256 td / np.timedelta64(1, "M") 257 258Dividing or multiplying a ``timedelta64[ns]`` Series by an integer or integer Series 259yields another ``timedelta64[ns]`` dtypes Series. 260 261.. ipython:: python 262 263 td * -1 264 td * pd.Series([1, 2, 3, 4]) 265 266Rounded division (floor-division) of a ``timedelta64[ns]`` Series by a scalar 267``Timedelta`` gives a series of integers. 268 269.. ipython:: python 270 271 td // pd.Timedelta(days=3, hours=4) 272 pd.Timedelta(days=3, hours=4) // td 273 274.. _timedeltas.mod_divmod: 275 276The mod (%) and divmod operations are defined for ``Timedelta`` when operating with another timedelta-like or with a numeric argument. 277 278.. ipython:: python 279 280 pd.Timedelta(hours=37) % datetime.timedelta(hours=2) 281 282 # divmod against a timedelta-like returns a pair (int, Timedelta) 283 divmod(datetime.timedelta(hours=2), pd.Timedelta(minutes=11)) 284 285 # divmod against a numeric returns a pair (Timedelta, Timedelta) 286 divmod(pd.Timedelta(hours=25), 86400000000000) 287 288Attributes 289---------- 290 291You can access various components of the ``Timedelta`` or ``TimedeltaIndex`` directly using the attributes ``days,seconds,microseconds,nanoseconds``. These are identical to the values returned by ``datetime.timedelta``, in that, for example, the ``.seconds`` attribute represents the number of seconds >= 0 and < 1 day. These are signed according to whether the ``Timedelta`` is signed. 292 293These operations can also be directly accessed via the ``.dt`` property of the ``Series`` as well. 294 295.. note:: 296 297 Note that the attributes are NOT the displayed values of the ``Timedelta``. Use ``.components`` to retrieve the displayed values. 298 299For a ``Series``: 300 301.. ipython:: python 302 303 td.dt.days 304 td.dt.seconds 305 306You can access the value of the fields for a scalar ``Timedelta`` directly. 307 308.. ipython:: python 309 310 tds = pd.Timedelta("31 days 5 min 3 sec") 311 tds.days 312 tds.seconds 313 (-tds).seconds 314 315You can use the ``.components`` property to access a reduced form of the timedelta. This returns a ``DataFrame`` indexed 316similarly to the ``Series``. These are the *displayed* values of the ``Timedelta``. 317 318.. ipython:: python 319 320 td.dt.components 321 td.dt.components.seconds 322 323.. _timedeltas.isoformat: 324 325You can convert a ``Timedelta`` to an `ISO 8601 Duration`_ string with the 326``.isoformat`` method 327 328.. ipython:: python 329 330 pd.Timedelta( 331 days=6, minutes=50, seconds=3, milliseconds=10, microseconds=10, nanoseconds=12 332 ).isoformat() 333 334.. _ISO 8601 Duration: https://en.wikipedia.org/wiki/ISO_8601#Durations 335 336.. _timedeltas.index: 337 338TimedeltaIndex 339-------------- 340 341To generate an index with time delta, you can use either the :class:`TimedeltaIndex` or 342the :func:`timedelta_range` constructor. 343 344Using ``TimedeltaIndex`` you can pass string-like, ``Timedelta``, ``timedelta``, 345or ``np.timedelta64`` objects. Passing ``np.nan/pd.NaT/nat`` will represent missing values. 346 347.. ipython:: python 348 349 pd.TimedeltaIndex( 350 [ 351 "1 days", 352 "1 days, 00:00:05", 353 np.timedelta64(2, "D"), 354 datetime.timedelta(days=2, seconds=2), 355 ] 356 ) 357 358The string 'infer' can be passed in order to set the frequency of the index as the 359inferred frequency upon creation: 360 361.. ipython:: python 362 363 pd.TimedeltaIndex(["0 days", "10 days", "20 days"], freq="infer") 364 365Generating ranges of time deltas 366~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 367 368Similar to :func:`date_range`, you can construct regular ranges of a ``TimedeltaIndex`` 369using :func:`timedelta_range`. The default frequency for ``timedelta_range`` is 370calendar day: 371 372.. ipython:: python 373 374 pd.timedelta_range(start="1 days", periods=5) 375 376Various combinations of ``start``, ``end``, and ``periods`` can be used with 377``timedelta_range``: 378 379.. ipython:: python 380 381 pd.timedelta_range(start="1 days", end="5 days") 382 383 pd.timedelta_range(end="10 days", periods=4) 384 385The ``freq`` parameter can passed a variety of :ref:`frequency aliases <timeseries.offset_aliases>`: 386 387.. ipython:: python 388 389 pd.timedelta_range(start="1 days", end="2 days", freq="30T") 390 391 pd.timedelta_range(start="1 days", periods=5, freq="2D5H") 392 393 394Specifying ``start``, ``end``, and ``periods`` will generate a range of evenly spaced 395timedeltas from ``start`` to ``end`` inclusively, with ``periods`` number of elements 396in the resulting ``TimedeltaIndex``: 397 398.. ipython:: python 399 400 pd.timedelta_range("0 days", "4 days", periods=5) 401 402 pd.timedelta_range("0 days", "4 days", periods=10) 403 404Using the TimedeltaIndex 405~~~~~~~~~~~~~~~~~~~~~~~~ 406 407Similarly to other of the datetime-like indices, ``DatetimeIndex`` and ``PeriodIndex``, you can use 408``TimedeltaIndex`` as the index of pandas objects. 409 410.. ipython:: python 411 412 s = pd.Series( 413 np.arange(100), 414 index=pd.timedelta_range("1 days", periods=100, freq="h"), 415 ) 416 s 417 418Selections work similarly, with coercion on string-likes and slices: 419 420.. ipython:: python 421 422 s["1 day":"2 day"] 423 s["1 day 01:00:00"] 424 s[pd.Timedelta("1 day 1h")] 425 426Furthermore you can use partial string selection and the range will be inferred: 427 428.. ipython:: python 429 430 s["1 day":"1 day 5 hours"] 431 432Operations 433~~~~~~~~~~ 434 435Finally, the combination of ``TimedeltaIndex`` with ``DatetimeIndex`` allow certain combination operations that are NaT preserving: 436 437.. ipython:: python 438 439 tdi = pd.TimedeltaIndex(["1 days", pd.NaT, "2 days"]) 440 tdi.to_list() 441 dti = pd.date_range("20130101", periods=3) 442 dti.to_list() 443 (dti + tdi).to_list() 444 (dti - tdi).to_list() 445 446Conversions 447~~~~~~~~~~~ 448 449Similarly to frequency conversion on a ``Series`` above, you can convert these indices to yield another Index. 450 451.. ipython:: python 452 453 tdi / np.timedelta64(1, "s") 454 tdi.astype("timedelta64[s]") 455 456Scalars type ops work as well. These can potentially return a *different* type of index. 457 458.. ipython:: python 459 460 # adding or timedelta and date -> datelike 461 tdi + pd.Timestamp("20130101") 462 463 # subtraction of a date and a timedelta -> datelike 464 # note that trying to subtract a date from a Timedelta will raise an exception 465 (pd.Timestamp("20130101") - tdi).to_list() 466 467 # timedelta + timedelta -> timedelta 468 tdi + pd.Timedelta("10 days") 469 470 # division can result in a Timedelta if the divisor is an integer 471 tdi / 2 472 473 # or a Float64Index if the divisor is a Timedelta 474 tdi / tdi[0] 475 476.. _timedeltas.resampling: 477 478Resampling 479---------- 480 481Similar to :ref:`timeseries resampling <timeseries.resampling>`, we can resample with a ``TimedeltaIndex``. 482 483.. ipython:: python 484 485 s.resample("D").mean() 486