Movatterモバイル変換


[0]ホーム

URL:


Skip to main content
Ctrl+K

Time deltas#

Timedeltas are differences in times, expressed in difference units, e.g. days, hours, minutes,seconds. They can be both positive and negative.

Timedelta is a subclass ofdatetime.timedelta, and behaves in a similar manner,but allows compatibility withnp.timedelta64 types as well as a host of custom representation,parsing, and attributes.

Parsing#

You can construct aTimedelta scalar through various arguments, includingISO 8601 Duration strings.

In [1]:importdatetime# stringsIn [2]:pd.Timedelta("1 days")Out[2]:Timedelta('1 days 00:00:00')In [3]:pd.Timedelta("1 days 00:00:00")Out[3]:Timedelta('1 days 00:00:00')In [4]:pd.Timedelta("1 days 2 hours")Out[4]:Timedelta('1 days 02:00:00')In [5]:pd.Timedelta("-1 days 2 min 3us")Out[5]:Timedelta('-2 days +23:57:59.999997')# like datetime.timedelta# note: these MUST be specified as keyword argumentsIn [6]:pd.Timedelta(days=1,seconds=1)Out[6]:Timedelta('1 days 00:00:01')# integers with a unitIn [7]:pd.Timedelta(1,unit="d")Out[7]:Timedelta('1 days 00:00:00')# from a datetime.timedelta/np.timedelta64In [8]:pd.Timedelta(datetime.timedelta(days=1,seconds=1))Out[8]:Timedelta('1 days 00:00:01')In [9]:pd.Timedelta(np.timedelta64(1,"ms"))Out[9]:Timedelta('0 days 00:00:00.001000')# negative Timedeltas have this string repr# to be more consistent with datetime.timedelta conventionsIn [10]:pd.Timedelta("-1us")Out[10]:Timedelta('-1 days +23:59:59.999999')# a NaTIn [11]:pd.Timedelta("nan")Out[11]:NaTIn [12]:pd.Timedelta("nat")Out[12]:NaT# ISO 8601 Duration stringsIn [13]:pd.Timedelta("P0DT0H1M0S")Out[13]:Timedelta('0 days 00:01:00')In [14]:pd.Timedelta("P0DT0H0M0.000000123S")Out[14]:Timedelta('0 days 00:00:00.000000123')

DateOffsets (Day,Hour,Minute,Second,Milli,Micro,Nano) can also be used in construction.

In [15]:pd.Timedelta(pd.offsets.Second(2))Out[15]:Timedelta('0 days 00:00:02')

Further, operations among the scalars yield another scalarTimedelta.

In [16]:pd.Timedelta(pd.offsets.Day(2))+pd.Timedelta(pd.offsets.Second(2))+pd.Timedelta(   ....:"00:00:00.000123"   ....:)   ....:Out[16]:Timedelta('2 days 00:00:02.000123')

to_timedelta#

Using the top-levelpd.to_timedelta, you can convert a scalar, array, list,or Series from a recognized timedelta format / value into aTimedelta type.It will construct Series if the input is a Series, a scalar if the input isscalar-like, otherwise it will output aTimedeltaIndex.

You can parse a single string to a Timedelta:

In [17]:pd.to_timedelta("1 days 06:05:01.00003")Out[17]:Timedelta('1 days 06:05:01.000030')In [18]:pd.to_timedelta("15.5us")Out[18]:Timedelta('0 days 00:00:00.000015500')

or a list/array of strings:

In [19]:pd.to_timedelta(["1 days 06:05:01.00003","15.5us","nan"])Out[19]:TimedeltaIndex(['1 days 06:05:01.000030', '0 days 00:00:00.000015500', NaT], dtype='timedelta64[ns]', freq=None)

Theunit keyword argument specifies the unit of the Timedelta if the inputis numeric:

In [20]:pd.to_timedelta(np.arange(5),unit="s")Out[20]:TimedeltaIndex(['0 days 00:00:00', '0 days 00:00:01', '0 days 00:00:02',                '0 days 00:00:03', '0 days 00:00:04'],               dtype='timedelta64[ns]', freq=None)In [21]:pd.to_timedelta(np.arange(5),unit="d")Out[21]:TimedeltaIndex(['0 days', '1 days', '2 days', '3 days', '4 days'], dtype='timedelta64[ns]', freq=None)

Warning

If a string or array of strings is passed as an input then theunit keywordargument will be ignored. If a string without units is passed then the defaultunit of nanoseconds is assumed.

Timedelta limitations#

pandas representsTimedeltas in nanosecond resolution using64 bit integers. As such, the 64 bit integer limits determinetheTimedelta limits.

In [22]:pd.Timedelta.minOut[22]:Timedelta('-106752 days +00:12:43.145224193')In [23]:pd.Timedelta.maxOut[23]:Timedelta('106751 days 23:47:16.854775807')

Operations#

You can operate on Series/DataFrames and constructtimedelta64[ns] Series throughsubtraction operations ondatetime64[ns] Series, orTimestamps.

In [24]:s=pd.Series(pd.date_range("2012-1-1",periods=3,freq="D"))In [25]:td=pd.Series([pd.Timedelta(days=i)foriinrange(3)])In [26]:df=pd.DataFrame({"A":s,"B":td})In [27]:dfOut[27]:           A      B0 2012-01-01 0 days1 2012-01-02 1 days2 2012-01-03 2 daysIn [28]:df["C"]=df["A"]+df["B"]In [29]:dfOut[29]:           A      B          C0 2012-01-01 0 days 2012-01-011 2012-01-02 1 days 2012-01-032 2012-01-03 2 days 2012-01-05In [30]:df.dtypesOut[30]:A     datetime64[ns]B    timedelta64[ns]C     datetime64[ns]dtype: objectIn [31]:s-s.max()Out[31]:0   -2 days1   -1 days2    0 daysdtype: timedelta64[ns]In [32]:s-datetime.datetime(2011,1,1,3,5)Out[32]:0   364 days 20:55:001   365 days 20:55:002   366 days 20:55:00dtype: timedelta64[ns]In [33]:s+datetime.timedelta(minutes=5)Out[33]:0   2012-01-01 00:05:001   2012-01-02 00:05:002   2012-01-03 00:05:00dtype: datetime64[ns]In [34]:s+pd.offsets.Minute(5)Out[34]:0   2012-01-01 00:05:001   2012-01-02 00:05:002   2012-01-03 00:05:00dtype: datetime64[ns]In [35]:s+pd.offsets.Minute(5)+pd.offsets.Milli(5)Out[35]:0   2012-01-01 00:05:00.0051   2012-01-02 00:05:00.0052   2012-01-03 00:05:00.005dtype: datetime64[ns]

Operations with scalars from atimedelta64[ns] series:

In [36]:y=s-s[0]In [37]:yOut[37]:0   0 days1   1 days2   2 daysdtype: timedelta64[ns]

Series of timedeltas withNaT values are supported:

In [38]:y=s-s.shift()In [39]:yOut[39]:0      NaT1   1 days2   1 daysdtype: timedelta64[ns]

Elements can be set toNaT usingnp.nan analogously to datetimes:

In [40]:y[1]=np.nanIn [41]:yOut[41]:0      NaT1      NaT2   1 daysdtype: timedelta64[ns]

Operands can also appear in a reversed order (a singular object operated with a Series):

In [42]:s.max()-sOut[42]:0   2 days1   1 days2   0 daysdtype: timedelta64[ns]In [43]:datetime.datetime(2011,1,1,3,5)-sOut[43]:0   -365 days +03:05:001   -366 days +03:05:002   -367 days +03:05:00dtype: timedelta64[ns]In [44]:datetime.timedelta(minutes=5)+sOut[44]:0   2012-01-01 00:05:001   2012-01-02 00:05:002   2012-01-03 00:05:00dtype: datetime64[ns]

min,max and the correspondingidxmin,idxmax operations are supported on frames:

In [45]:A=s-pd.Timestamp("20120101")-pd.Timedelta("00:05:05")In [46]:B=s-pd.Series(pd.date_range("2012-1-2",periods=3,freq="D"))In [47]:df=pd.DataFrame({"A":A,"B":B})In [48]:dfOut[48]:                  A       B0 -1 days +23:54:55 -1 days1   0 days 23:54:55 -1 days2   1 days 23:54:55 -1 daysIn [49]:df.min()Out[49]:A   -1 days +23:54:55B   -1 days +00:00:00dtype: timedelta64[ns]In [50]:df.min(axis=1)Out[50]:0   -1 days1   -1 days2   -1 daysdtype: timedelta64[ns]In [51]:df.idxmin()Out[51]:A    0B    0dtype: int64In [52]:df.idxmax()Out[52]:A    2B    0dtype: int64

min,max,idxmin,idxmax operations are supported on Series as well. A scalar result will be aTimedelta.

In [53]:df.min().max()Out[53]:Timedelta('-1 days +23:54:55')In [54]:df.min(axis=1).min()Out[54]:Timedelta('-1 days +00:00:00')In [55]:df.min().idxmax()Out[55]:'A'In [56]:df.min(axis=1).idxmin()Out[56]:0

You can fillna on timedeltas, passing a timedelta to get a particular value.

In [57]:y.fillna(pd.Timedelta(0))Out[57]:0   0 days1   0 days2   1 daysdtype: timedelta64[ns]In [58]:y.fillna(pd.Timedelta(10,unit="s"))Out[58]:0   0 days 00:00:101   0 days 00:00:102   1 days 00:00:00dtype: timedelta64[ns]In [59]:y.fillna(pd.Timedelta("-1 days, 00:00:05"))Out[59]:0   -1 days +00:00:051   -1 days +00:00:052     1 days 00:00:00dtype: timedelta64[ns]

You can also negate, multiply and useabs onTimedeltas:

In [60]:td1=pd.Timedelta("-1 days 2 hours 3 seconds")In [61]:td1Out[61]:Timedelta('-2 days +21:59:57')In [62]:-1*td1Out[62]:Timedelta('1 days 02:00:03')In [63]:-td1Out[63]:Timedelta('1 days 02:00:03')In [64]:abs(td1)Out[64]:Timedelta('1 days 02:00:03')

Reductions#

Numeric reduction operation fortimedelta64[ns] will returnTimedelta objects. As usualNaT are skipped during evaluation.

In [65]:y2=pd.Series(   ....:pd.to_timedelta(["-1 days +00:00:05","nat","-1 days +00:00:05","1 days"])   ....:)   ....:In [66]:y2Out[66]:0   -1 days +00:00:051                 NaT2   -1 days +00:00:053     1 days 00:00:00dtype: timedelta64[ns]In [67]:y2.mean()Out[67]:Timedelta('-1 days +16:00:03.333333334')In [68]:y2.median()Out[68]:Timedelta('-1 days +00:00:05')In [69]:y2.quantile(0.1)Out[69]:Timedelta('-1 days +00:00:05')In [70]:y2.sum()Out[70]:Timedelta('-1 days +00:00:10')

Frequency conversion#

Timedelta Series andTimedeltaIndex, andTimedelta can be converted to other frequencies by astyping to a specific timedelta dtype.

In [71]:december=pd.Series(pd.date_range("20121201",periods=4))In [72]:january=pd.Series(pd.date_range("20130101",periods=4))In [73]:td=january-decemberIn [74]:td[2]+=datetime.timedelta(minutes=5,seconds=3)In [75]:td[3]=np.nanIn [76]:tdOut[76]:0   31 days 00:00:001   31 days 00:00:002   31 days 00:05:033                NaTdtype: timedelta64[ns]# to secondsIn [77]:td.astype("timedelta64[s]")Out[77]:0   31 days 00:00:001   31 days 00:00:002   31 days 00:05:033                NaTdtype: timedelta64[s]

For timedelta64 resolutions other than the supported “s”, “ms”, “us”, “ns”,an alternative is to divide by another timedelta object. Note that division by the NumPy scalar is true division, while astyping is equivalent of floor division.

# to daysIn [78]:td/np.timedelta64(1,"D")Out[78]:0    31.0000001    31.0000002    31.0035073          NaNdtype: float64

Dividing or multiplying atimedelta64[ns] Series by an integer or integer Seriesyields anothertimedelta64[ns] dtypes Series.

In [79]:td*-1Out[79]:0   -31 days +00:00:001   -31 days +00:00:002   -32 days +23:54:573                  NaTdtype: timedelta64[ns]In [80]:td*pd.Series([1,2,3,4])Out[80]:0   31 days 00:00:001   62 days 00:00:002   93 days 00:15:093                NaTdtype: timedelta64[ns]

Rounded division (floor-division) of atimedelta64[ns] Series by a scalarTimedelta gives a series of integers.

In [81]:td//pd.Timedelta(days=3,hours=4)Out[81]:0    9.01    9.02    9.03    NaNdtype: float64In [82]:pd.Timedelta(days=3,hours=4)//tdOut[82]:0    0.01    0.02    0.03    NaNdtype: float64

The mod (%) and divmod operations are defined forTimedelta when operating with another timedelta-like or with a numeric argument.

In [83]:pd.Timedelta(hours=37)%datetime.timedelta(hours=2)Out[83]:Timedelta('0 days 01:00:00')# divmod against a timedelta-like returns a pair (int, Timedelta)In [84]:divmod(datetime.timedelta(hours=2),pd.Timedelta(minutes=11))Out[84]:(10, Timedelta('0 days 00:10:00'))# divmod against a numeric returns a pair (Timedelta, Timedelta)In [85]:divmod(pd.Timedelta(hours=25),86400000000000)Out[85]:(Timedelta('0 days 00:00:00.000000001'), Timedelta('0 days 01:00:00'))

Attributes#

You can access various components of theTimedelta orTimedeltaIndex directly using the attributesdays,seconds,microseconds,nanoseconds. These are identical to the values returned bydatetime.timedelta, in that, for example, the.seconds attribute represents the number of seconds >= 0 and < 1 day. These are signed according to whether theTimedelta is signed.

These operations can also be directly accessed via the.dt property of theSeries as well.

Note

Note that the attributes are NOT the displayed values of theTimedelta. Use.components to retrieve the displayed values.

For aSeries:

In [86]:td.dt.daysOut[86]:0    31.01    31.02    31.03     NaNdtype: float64In [87]:td.dt.secondsOut[87]:0      0.01      0.02    303.03      NaNdtype: float64

You can access the value of the fields for a scalarTimedelta directly.

In [88]:tds=pd.Timedelta("31 days 5 min 3 sec")In [89]:tds.daysOut[89]:31In [90]:tds.secondsOut[90]:303In [91]:(-tds).secondsOut[91]:86097

You can use the.components property to access a reduced form of the timedelta. This returns aDataFrame indexedsimilarly to theSeries. These are thedisplayed values of theTimedelta.

In [92]:td.dt.componentsOut[92]:   days  hours  minutes  seconds  milliseconds  microseconds  nanoseconds0  31.0    0.0      0.0      0.0           0.0           0.0          0.01  31.0    0.0      0.0      0.0           0.0           0.0          0.02  31.0    0.0      5.0      3.0           0.0           0.0          0.03   NaN    NaN      NaN      NaN           NaN           NaN          NaNIn [93]:td.dt.components.secondsOut[93]:0    0.01    0.02    3.03    NaNName: seconds, dtype: float64

You can convert aTimedelta to anISO 8601 Duration string with the.isoformat method

In [94]:pd.Timedelta(   ....:days=6,minutes=50,seconds=3,milliseconds=10,microseconds=10,nanoseconds=12   ....:).isoformat()   ....:Out[94]:'P6DT0H50M3.010010012S'

TimedeltaIndex#

To generate an index with time delta, you can use either theTimedeltaIndex orthetimedelta_range() constructor.

UsingTimedeltaIndex you can pass string-like,Timedelta,timedelta,ornp.timedelta64 objects. Passingnp.nan/pd.NaT/nat will represent missing values.

In [95]:pd.TimedeltaIndex(   ....:[   ....:"1 days",   ....:"1 days, 00:00:05",   ....:np.timedelta64(2,"D"),   ....:datetime.timedelta(days=2,seconds=2),   ....:]   ....:)   ....:Out[95]:TimedeltaIndex(['1 days 00:00:00', '1 days 00:00:05', '2 days 00:00:00',                '2 days 00:00:02'],               dtype='timedelta64[ns]', freq=None)

The string ‘infer’ can be passed in order to set the frequency of the index as theinferred frequency upon creation:

In [96]:pd.TimedeltaIndex(["0 days","10 days","20 days"],freq="infer")Out[96]:TimedeltaIndex(['0 days', '10 days', '20 days'], dtype='timedelta64[ns]', freq='10D')

Generating ranges of time deltas#

Similar todate_range(), you can construct regular ranges of aTimedeltaIndexusingtimedelta_range(). The default frequency fortimedelta_range iscalendar day:

In [97]:pd.timedelta_range(start="1 days",periods=5)Out[97]:TimedeltaIndex(['1 days', '2 days', '3 days', '4 days', '5 days'], dtype='timedelta64[ns]', freq='D')

Various combinations ofstart,end, andperiods can be used withtimedelta_range:

In [98]:pd.timedelta_range(start="1 days",end="5 days")Out[98]:TimedeltaIndex(['1 days', '2 days', '3 days', '4 days', '5 days'], dtype='timedelta64[ns]', freq='D')In [99]:pd.timedelta_range(end="10 days",periods=4)Out[99]:TimedeltaIndex(['7 days', '8 days', '9 days', '10 days'], dtype='timedelta64[ns]', freq='D')

Thefreq parameter can passed a variety offrequency aliases:

In [100]:pd.timedelta_range(start="1 days",end="2 days",freq="30min")Out[100]:TimedeltaIndex(['1 days 00:00:00', '1 days 00:30:00', '1 days 01:00:00',                '1 days 01:30:00', '1 days 02:00:00', '1 days 02:30:00',                '1 days 03:00:00', '1 days 03:30:00', '1 days 04:00:00',                '1 days 04:30:00', '1 days 05:00:00', '1 days 05:30:00',                '1 days 06:00:00', '1 days 06:30:00', '1 days 07:00:00',                '1 days 07:30:00', '1 days 08:00:00', '1 days 08:30:00',                '1 days 09:00:00', '1 days 09:30:00', '1 days 10:00:00',                '1 days 10:30:00', '1 days 11:00:00', '1 days 11:30:00',                '1 days 12:00:00', '1 days 12:30:00', '1 days 13:00:00',                '1 days 13:30:00', '1 days 14:00:00', '1 days 14:30:00',                '1 days 15:00:00', '1 days 15:30:00', '1 days 16:00:00',                '1 days 16:30:00', '1 days 17:00:00', '1 days 17:30:00',                '1 days 18:00:00', '1 days 18:30:00', '1 days 19:00:00',                '1 days 19:30:00', '1 days 20:00:00', '1 days 20:30:00',                '1 days 21:00:00', '1 days 21:30:00', '1 days 22:00:00',                '1 days 22:30:00', '1 days 23:00:00', '1 days 23:30:00',                '2 days 00:00:00'],               dtype='timedelta64[ns]', freq='30min')In [101]:pd.timedelta_range(start="1 days",periods=5,freq="2D5h")Out[101]:TimedeltaIndex(['1 days 00:00:00', '3 days 05:00:00', '5 days 10:00:00',                '7 days 15:00:00', '9 days 20:00:00'],               dtype='timedelta64[ns]', freq='53h')

Specifyingstart,end, andperiods will generate a range of evenly spacedtimedeltas fromstart toend inclusively, withperiods number of elementsin the resultingTimedeltaIndex:

In [102]:pd.timedelta_range("0 days","4 days",periods=5)Out[102]:TimedeltaIndex(['0 days', '1 days', '2 days', '3 days', '4 days'], dtype='timedelta64[ns]', freq=None)In [103]:pd.timedelta_range("0 days","4 days",periods=10)Out[103]:TimedeltaIndex(['0 days 00:00:00', '0 days 10:40:00', '0 days 21:20:00',                '1 days 08:00:00', '1 days 18:40:00', '2 days 05:20:00',                '2 days 16:00:00', '3 days 02:40:00', '3 days 13:20:00',                '4 days 00:00:00'],               dtype='timedelta64[ns]', freq=None)

Using the TimedeltaIndex#

Similarly to other of the datetime-like indices,DatetimeIndex andPeriodIndex, you can useTimedeltaIndex as the index of pandas objects.

In [104]:s=pd.Series(   .....:np.arange(100),   .....:index=pd.timedelta_range("1 days",periods=100,freq="h"),   .....:)   .....:In [105]:sOut[105]:1 days 00:00:00     01 days 01:00:00     11 days 02:00:00     21 days 03:00:00     31 days 04:00:00     4                   ..4 days 23:00:00    955 days 00:00:00    965 days 01:00:00    975 days 02:00:00    985 days 03:00:00    99Freq: h, Length: 100, dtype: int64

Selections work similarly, with coercion on string-likes and slices:

In [106]:s["1 day":"2 day"]Out[106]:1 days 00:00:00     01 days 01:00:00     11 days 02:00:00     21 days 03:00:00     31 days 04:00:00     4                   ..2 days 19:00:00    432 days 20:00:00    442 days 21:00:00    452 days 22:00:00    462 days 23:00:00    47Freq: h, Length: 48, dtype: int64In [107]:s["1 day 01:00:00"]Out[107]:1In [108]:s[pd.Timedelta("1 day 1h")]Out[108]:1

Furthermore you can use partial string selection and the range will be inferred:

In [109]:s["1 day":"1 day 5 hours"]Out[109]:1 days 00:00:00    01 days 01:00:00    11 days 02:00:00    21 days 03:00:00    31 days 04:00:00    41 days 05:00:00    5Freq: h, dtype: int64

Operations#

Finally, the combination ofTimedeltaIndex withDatetimeIndex allow certain combination operations that are NaT preserving:

In [110]:tdi=pd.TimedeltaIndex(["1 days",pd.NaT,"2 days"])In [111]:tdi.to_list()Out[111]:[Timedelta('1 days 00:00:00'), NaT, Timedelta('2 days 00:00:00')]In [112]:dti=pd.date_range("20130101",periods=3)In [113]:dti.to_list()Out[113]:[Timestamp('2013-01-01 00:00:00'), Timestamp('2013-01-02 00:00:00'), Timestamp('2013-01-03 00:00:00')]In [114]:(dti+tdi).to_list()Out[114]:[Timestamp('2013-01-02 00:00:00'), NaT, Timestamp('2013-01-05 00:00:00')]In [115]:(dti-tdi).to_list()Out[115]:[Timestamp('2012-12-31 00:00:00'), NaT, Timestamp('2013-01-01 00:00:00')]

Conversions#

Similarly to frequency conversion on aSeries above, you can convert these indices to yield another Index.

In [116]:tdi/np.timedelta64(1,"s")Out[116]:Index([86400.0, nan, 172800.0], dtype='float64')In [117]:tdi.astype("timedelta64[s]")Out[117]:TimedeltaIndex(['1 days', NaT, '2 days'], dtype='timedelta64[s]', freq=None)

Scalars type ops work as well. These can potentially return adifferent type of index.

# adding or timedelta and date -> datelikeIn [118]:tdi+pd.Timestamp("20130101")Out[118]:DatetimeIndex(['2013-01-02', 'NaT', '2013-01-03'], dtype='datetime64[ns]', freq=None)# subtraction of a date and a timedelta -> datelike# note that trying to subtract a date from a Timedelta will raise an exceptionIn [119]:(pd.Timestamp("20130101")-tdi).to_list()Out[119]:[Timestamp('2012-12-31 00:00:00'), NaT, Timestamp('2012-12-30 00:00:00')]# timedelta + timedelta -> timedeltaIn [120]:tdi+pd.Timedelta("10 days")Out[120]:TimedeltaIndex(['11 days', NaT, '12 days'], dtype='timedelta64[ns]', freq=None)# division can result in a Timedelta if the divisor is an integerIn [121]:tdi/2Out[121]:TimedeltaIndex(['0 days 12:00:00', NaT, '1 days 00:00:00'], dtype='timedelta64[ns]', freq=None)# or a float64 Index if the divisor is a TimedeltaIn [122]:tdi/tdi[0]Out[122]:Index([1.0, nan, 2.0], dtype='float64')

Resampling#

Similar totimeseries resampling, we can resample with aTimedeltaIndex.

In [123]:s.resample("D").mean()Out[123]:1 days    11.52 days    35.53 days    59.54 days    83.55 days    97.5Freq: D, dtype: float64

[8]ページ先頭

©2009-2025 Movatter.jp