Spec-Zone.ru › pandas 0.19

Временные интервалы

Примечание

Начиная с версии v0.15.0, мы вводим новый скалярный тип Timedelta, который является подклассом datetime.timedelta, и ведет себя аналогичным образом, но также обеспечивает совместимость с типами np.timedelta64 и широким набором пользовательских представлений, парсинга и атрибутов.

Временные интервалы представляют собой разницу во времени, выраженную в единицах измерения, например, днях, часах, минутах, секундах. Они могут быть как положительными, так и отрицательными.

Парсинг

Вы можете создать скаляр Timedelta с помощью различных аргументов:

# strings
In [1]: Timedelta('1 days')
Out[1]: Timedelta('1 days 00:00:00')

In [2]: Timedelta('1 days 00:00:00')
Out[2]: Timedelta('1 days 00:00:00')

In [3]: Timedelta('1 days 2 hours')
Out[3]: Timedelta('1 days 02:00:00')

In [4]: Timedelta('-1 days 2 min 3us')
Out[4]: Timedelta('-2 days +23:57:59.999997')

# like datetime.timedelta
# note: these MUST be specified as keyword arguments
In [5]: Timedelta(days=1, seconds=1)
Out[5]: Timedelta('1 days 00:00:01')

# integers with a unit
In [6]: Timedelta(1, unit='d')
Out[6]: Timedelta('1 days 00:00:00')

# from a timedelta/np.timedelta64
In [7]: Timedelta(timedelta(days=1, seconds=1))
Out[7]: Timedelta('1 days 00:00:01')

In [8]: Timedelta(np.timedelta64(1, 'ms'))
Out[8]: Timedelta('0 days 00:00:00.001000')

# negative Timedeltas have this string repr
# to be more consistent with datetime.timedelta conventions
In [9]: Timedelta('-1us')
Out[9]: Timedelta('-1 days +23:59:59.999999')

# a NaT
In [10]: Timedelta('nan')
Out[10]: NaT

In [11]: Timedelta('nat')
Out[11]: NaT

DateOffsets (Day, Hour, Minute, Second, Milli, Micro, Nano) также можно использовать при создании.

In [12]: Timedelta(Second(2))
Out[12]: Timedelta('0 days 00:00:02')

Кроме того, операции между скалярами дают другой скаляр Timedelta.

In [13]: Timedelta(Day(2)) + Timedelta(Second(2)) + Timedelta('00:00:00.000123')
Out[13]: Timedelta('2 days 00:00:02.000123')

to_timedelta

Предупреждение

До версии 0.15.0 pd.to_timedelta возвращал Series для ввода типа список/Series и np.timedelta64 для скалярного ввода. Теперь он возвращает TimedeltaIndex для ввода типа список, Series для ввода типа Series и Timedelta для скалярного ввода.

Аргументы pd.to_timedelta теперь (arg, unit='ns', box=True), ранее были (arg, box=True, unit='ns'), так как они более логичны.

Используя верхнеуровневый pd.to_timedelta, вы можете преобразовать скаляр, массив, список или Series из распознаваемого формата/значения временного интервала в тип Timedelta. Он создаст Series, если входной параметр — Series, скаляр, если входной параметр — скалярный, в противном случае выведет TimedeltaIndex.

Вы можете распарсить строку до значения Timedelta:

In [14]: to_timedelta('1 days 06:05:01.00003')
Out[14]: Timedelta('1 days 06:05:01.000030')

In [15]: to_timedelta('15.5us')
Out[15]: Timedelta('0 days 00:00:00.000015')

или список/массив строк:

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

Ключевой аргумент unit указывает единицу измерения Timedelta:

In [17]: to_timedelta(np.arange(5), unit='s')
Out[17]: TimedeltaIndex(['00:00:00', '00:00:01', '00:00:02', '00:00:03', '00:00:04'], dtype='timedelta64[ns]', freq=None)

In [18]: to_timedelta(np.arange(5), unit='d')
Out[18]: TimedeltaIndex(['0 days', '1 days', '2 days', '3 days', '4 days'], dtype='timedelta64[ns]', freq=None)

Ограничения временных интервалов

Pandas представляет Timedeltas с разрешением в наносекунды, используя 64-битные целые числа. Таким образом, пределы 64-битных целых чисел определяют Timedelta пределы.

In [19]: pd.Timedelta.min
Out[19]: Timedelta('-106752 days +00:12:43.145224')

In [20]: pd.Timedelta.max
Out[20]: Timedelta('106751 days 23:47:16.854775')

Операции

Вы можете выполнять операции с Series/DataFrames и создавать timedelta64[ns] Series путем вычитания операций над datetime64[ns] Series или Timestamps.

In [21]: s = Series(date_range('2012-1-1', periods=3, freq='D'))

In [22]: td = Series([ Timedelta(days=i) for i in range(3) ])

In [23]: df = DataFrame(dict(A = s, B = td))

In [24]: df
Out[24]: 
           A      B
0 2012-01-01 0 days
1 2012-01-02 1 days
2 2012-01-03 2 days

In [25]: df['C'] = df['A'] + df['B']

In [26]: df
Out[26]: 
           A      B          C
0 2012-01-01 0 days 2012-01-01
1 2012-01-02 1 days 2012-01-03
2 2012-01-03 2 days 2012-01-05

In [27]: df.dtypes
Out[27]: 
A     datetime64[ns]
B    timedelta64[ns]
C     datetime64[ns]
dtype: object

In [28]: s - s.max()
Out[28]: 
0   -2 days
1   -1 days
2    0 days
dtype: timedelta64[ns]

In [29]: s - datetime(2011, 1, 1, 3, 5)
Out[29]: 
0   364 days 20:55:00
1   365 days 20:55:00
2   366 days 20:55:00
dtype: timedelta64[ns]

In [30]: s + timedelta(minutes=5)
Out[30]: 
0   2012-01-01 00:05:00
1   2012-01-02 00:05:00
2   2012-01-03 00:05:00
dtype: datetime64[ns]

In [31]: s + Minute(5)
Out[31]: 
0   2012-01-01 00:05:00
1   2012-01-02 00:05:00
2   2012-01-03 00:05:00
dtype: datetime64[ns]

In [32]: s + Minute(5) + Milli(5)
Out[32]: 
0   2012-01-01 00:05:00.005
1   2012-01-02 00:05:00.005
2   2012-01-03 00:05:00.005
dtype: datetime64[ns]

Операции со скалярами из timedelta64[ns] ряда:

In [33]: y = s - s[0]

In [34]: y
Out[34]: 
0   0 days
1   1 days
2   2 days
dtype: timedelta64[ns]

Поддерживаются ряды временных интервалов со значениями NaT:

In [35]: y = s - s.shift()

In [36]: y
Out[36]: 
0      NaT
1   1 days
2   1 days
dtype: timedelta64[ns]

Элементы могут быть установлены в NaT с помощью np.nan аналогично датам:

In [37]: y[1] = np.nan

In [38]: y
Out[38]: 
0      NaT
1      NaT
2   1 days
dtype: timedelta64[ns]

Операнды также могут появляться в обратном порядке (единичный объект, с которым работает Series):

In [39]: s.max() - s
Out[39]: 
0   2 days
1   1 days
2   0 days
dtype: timedelta64[ns]

In [40]: datetime(2011, 1, 1, 3, 5) - s
Out[40]: 
0   -365 days +03:05:00
1   -366 days +03:05:00
2   -367 days +03:05:00
dtype: timedelta64[ns]

In [41]: timedelta(minutes=5) + s
Out[41]: 
0   2012-01-01 00:05:00
1   2012-01-02 00:05:00
2   2012-01-03 00:05:00
dtype: datetime64[ns]

min, max и соответствующие idxmin, idxmax операции поддерживаются для фреймов:

In [42]: A = s - Timestamp('20120101') - Timedelta('00:05:05')

In [43]: B = s - Series(date_range('2012-1-2', periods=3, freq='D'))

In [44]: df = DataFrame(dict(A=A, B=B))

In [45]: df
Out[45]: 
                  A       B
0 -1 days +23:54:55 -1 days
1   0 days 23:54:55 -1 days
2   1 days 23:54:55 -1 days

In [46]: df.min()
Out[46]: 
A   -1 days +23:54:55
B   -1 days +00:00:00
dtype: timedelta64[ns]

In [47]: df.min(axis=1)
Out[47]: 
0   -1 days
1   -1 days
2   -1 days
dtype: timedelta64[ns]

In [48]: df.idxmin()
Out[48]: 
A    0
B    0
dtype: int64

In [49]: df.idxmax()
Out[49]: 
A    2
B    0
dtype: int64

min, max, idxmin, idxmax операции поддерживаются для Series. Скалярный результат будет Timedelta.

In [50]: df.min().max()
Out[50]: Timedelta('-1 days +23:54:55')

In [51]: df.min(axis=1).min()
Out[51]: Timedelta('-1 days +00:00:00')

In [52]: df.min().idxmax()
Out[52]: 'A'

In [53]: df.min(axis=1).idxmin()
Out[53]: 0

Вы можете заполнить пропуски (fillna) для временных интервалов. Целые числа будут интерпретироваться как секунды. Вы можете передать временной интервал, чтобы получить определенное значение.

In [54]: y.fillna(0)
Out[54]: 
0   0 days
1   0 days
2   1 days
dtype: timedelta64[ns]

In [55]: y.fillna(10)
Out[55]: 
0   0 days 00:00:10
1   0 days 00:00:10
2   1 days 00:00:00
dtype: timedelta64[ns]

In [56]: y.fillna(Timedelta('-1 days, 00:00:05'))
Out[56]: 
0   -1 days +00:00:05
1   -1 days +00:00:05
2     1 days 00:00:00
dtype: timedelta64[ns]

Вы также можете изменять знак, умножать и использовать abs над Timedeltas:

In [57]: td1 = Timedelta('-1 days 2 hours 3 seconds')

In [58]: td1
Out[58]: Timedelta('-2 days +21:59:57')

In [59]: -1 * td1
Out[59]: Timedelta('1 days 02:00:03')

In [60]: - td1
Out[60]: Timedelta('1 days 02:00:03')

In [61]: abs(td1)
Out[61]: Timedelta('1 days 02:00:03')

Сводки

Числовая операция сводки для timedelta64[ns] вернет Timedelta объекты. Как обычно, NaT пропускаются во время вычислений.

In [62]: y2 = Series(to_timedelta(['-1 days +00:00:05', 'nat', '-1 days +00:00:05', '1 days']))

In [63]: y2
Out[63]: 
0   -1 days +00:00:05
1                 NaT
2   -1 days +00:00:05
3     1 days 00:00:00
dtype: timedelta64[ns]

In [64]: y2.mean()
Out[64]: Timedelta('-1 days +16:00:03.333333')

In [65]: y2.median()
Out[65]: Timedelta('-1 days +00:00:05')

In [66]: y2.quantile(.1)
Out[66]: Timedelta('-1 days +00:00:05')

In [67]: y2.sum()
Out[67]: Timedelta('-1 days +00:00:10')

Преобразование частоты

Новое в версии 0.13.

Ряды временных интервалов, TimedeltaIndex, и Timedelta скаляры могут быть преобразованы в другие «частоты» путем деления на другой временной интервал или путем приведения типа к определенному типу временного интервала. Эти операции дают Series и передают NaT -> nan. Обратите внимание, что деление на скаляр numpy — это истинное деление, а приведение типа эквивалентно целочисленному делению.

In [68]: td = Series(date_range('20130101', periods=4)) - \
   ....:      Series(date_range('20121201', periods=4))
   ....: 

In [69]: td[2] += timedelta(minutes=5, seconds=3)

In [70]: td[3] = np.nan

In [71]: td
Out[71]: 
0   31 days 00:00:00
1   31 days 00:00:00
2   31 days 00:05:03
3                NaT
dtype: timedelta64[ns]

# to days
In [72]: td / np.timedelta64(1, 'D')
Out[72]: 
0    31.000000
1    31.000000
2    31.003507
3          NaN
dtype: float64

In [73]: td.astype('timedelta64[D]')
Out[73]: 
0    31.0
1    31.0
2    31.0
3     NaN
dtype: float64

# to seconds
In [74]: td / np.timedelta64(1, 's')
Out[74]: 
0    2678400.0
1    2678400.0
2    2678703.0
3          NaN
dtype: float64

In [75]: td.astype('timedelta64[s]')
Out[75]: 
0    2678400.0
1    2678400.0
2    2678703.0
3          NaN
dtype: float64

# to months (these are constant months)
In [76]: td / np.timedelta64(1, 'M')
Out[76]: 
0    1.018501
1    1.018501
2    1.018617
3         NaN
dtype: float64

Деление или умножение timedelta64[ns] ряда на целое число или целочисленный Series дает другой timedelta64[ns] dtypes Series.

In [77]: td * -1
Out[77]: 
0   -31 days +00:00:00
1   -31 days +00:00:00
2   -32 days +23:54:57
3                  NaT
dtype: timedelta64[ns]

In [78]: td * Series([1, 2, 3, 4])
Out[78]: 
0   31 days 00:00:00
1   62 days 00:00:00
2   93 days 00:15:09
3                NaT
dtype: timedelta64[ns]

Атрибуты

Вы можете получить доступ к различным компонентам Timedelta или TimedeltaIndex напрямую, используя атрибуты days,seconds,microseconds,nanoseconds. Они идентичны значениям, возвращаемым datetime.timedelta, так что, например, атрибут .seconds представляет количество секунд ≥ 0 и < 1 день. Они имеют знак в соответствии со знаком Timedelta.

К этим операциям также можно получить доступ напрямую через свойство .dt объекта Series.

Примечание

Обратите внимание, что атрибуты НЕ являются отображаемыми значениями Timedelta. Используйте .components для получения отображаемых значений.

Для Series:

In [79]: td.dt.days
Out[79]: 
0    31.0
1    31.0
2    31.0
3     NaN
dtype: float64

In [80]: td.dt.seconds
Out[80]: 
0      0.0
1      0.0
2    303.0
3      NaN
dtype: float64

Вы можете получить доступ к значениям полей для скалярного Timedelta напрямую.

In [81]: tds = Timedelta('31 days 5 min 3 sec')

In [82]: tds.days
Out[82]: 31

In [83]: tds.seconds
Out[83]: 303

In [84]: (-tds).seconds
Out[84]: 86097

Вы можете использовать свойство .components для доступа к сокращенной форме временного интервала. Это возвращает DataFrame с индексом, аналогичным Series. Это отображаемые значения Timedelta.

In [85]: td.dt.components
Out[85]: 
   days  hours  minutes  seconds  milliseconds  microseconds  nanoseconds
0  31.0    0.0      0.0      0.0           0.0           0.0          0.0
1  31.0    0.0      0.0      0.0           0.0           0.0          0.0
2  31.0    0.0      5.0      3.0           0.0           0.0          0.0
3   NaN    NaN      NaN      NaN           NaN           NaN          NaN

In [86]: td.dt.components.seconds
Out[86]: 
0    0.0
1    0.0
2    3.0
3    NaN
Name: seconds, dtype: float64

Индекс временных интервалов

Новое в версии 0.15.0.

Для создания индекса с временным интервалом вы можете использовать либо TimedeltaIndex или конструктор timedelta_range.

Используя TimedeltaIndex вы можете передать строковые, Timedelta, timedelta, или np.timedelta64 объекты. Передача np.nan/pd.NaT/nat будет представлять пропущенные значения.

In [87]: TimedeltaIndex(['1 days', '1 days, 00:00:05',
   ....:                 np.timedelta64(2,'D'), timedelta(days=2,seconds=2)])
   ....: 
Out[87]: 
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)

Аналогично date_range, вы можете построить регулярные диапазоны TimedeltaIndex:

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

In [89]: timedelta_range(start='1 days', end='2 days', freq='30T')
Out[89]: 
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='30T')

Использование индекса временных интервалов

Аналогично другим индексам, подобным датам, DatetimeIndex и PeriodIndex, вы можете использовать TimedeltaIndex в качестве индекса объектов pandas.

In [90]: s = Series(np.arange(100),
   ....:            index=timedelta_range('1 days', periods=100, freq='h'))
   ....: 

In [91]: s
Out[91]: 
1 days 00:00:00     0
1 days 01:00:00     1
1 days 02:00:00     2
1 days 03:00:00     3
1 days 04:00:00     4
1 days 05:00:00     5
1 days 06:00:00     6
                   ..
4 days 21:00:00    93
4 days 22:00:00    94
4 days 23:00:00    95
5 days 00:00:00    96
5 days 01:00:00    97
5 days 02:00:00    98
5 days 03:00:00    99
Freq: H, dtype: int64

Выборка работает аналогично, с приведением типа для строковых значений и срезов:

In [92]: s['1 day':'2 day']
Out[92]: 
1 days 00:00:00     0
1 days 01:00:00     1
1 days 02:00:00     2
1 days 03:00:00     3
1 days 04:00:00     4
1 days 05:00:00     5
1 days 06:00:00     6
                   ..
2 days 17:00:00    41
2 days 18:00:00    42
2 days 19:00:00    43
2 days 20:00:00    44
2 days 21:00:00    45
2 days 22:00:00    46
2 days 23:00:00    47
Freq: H, dtype: int64

In [93]: s['1 day 01:00:00']
Out[93]: 1

In [94]: s[Timedelta('1 day 1h')]
Out[94]: 1

Кроме того, вы можете использовать частичный строковый выбор, и диапазон будет определен:

In [95]: s['1 day':'1 day 5 hours']
Out[95]: 
1 days 00:00:00    0
1 days 01:00:00    1
1 days 02:00:00    2
1 days 03:00:00    3
1 days 04:00:00    4
1 days 05:00:00    5
Freq: H, dtype: int64

Операции

Наконец, сочетание TimedeltaIndex и DatetimeIndex позволяют определенные комбинированные операции, которые сохраняют NaT:

In [96]: tdi = TimedeltaIndex(['1 days', pd.NaT, '2 days'])

In [97]: tdi.tolist()
Out[97]: [Timedelta('1 days 00:00:00'), NaT, Timedelta('2 days 00:00:00')]

In [98]: dti = date_range('20130101', periods=3)

In [99]: dti.tolist()
Out[99]: 
[Timestamp('2013-01-01 00:00:00', freq='D'),
 Timestamp('2013-01-02 00:00:00', freq='D'),
 Timestamp('2013-01-03 00:00:00', freq='D')]

In [100]: (dti + tdi).tolist()
Out[100]: [Timestamp('2013-01-02 00:00:00'), NaT, Timestamp('2013-01-05 00:00:00')]

In [101]: (dti - tdi).tolist()
Out[101]: [Timestamp('2012-12-31 00:00:00'), NaT, Timestamp('2013-01-01 00:00:00')]

Преобразования

Аналогично преобразованию частоты в Series выше, вы можете преобразовать эти индексы для получения другого индекса.

In [102]: tdi / np.timedelta64(1,'s')
Out[102]: Float64Index([86400.0, nan, 172800.0], dtype='float64')

In [103]: tdi.astype('timedelta64[s]')
Out[103]: Float64Index([86400.0, nan, 172800.0], dtype='float64')

Скалярные операции типа также работают. Они потенциально могут возвращать разный тип индекса.

# adding or timedelta and date -> datelike
In [104]: tdi + Timestamp('20130101')
Out[104]: 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 exception
In [105]: (Timestamp('20130101') - tdi).tolist()
Out[105]: [Timestamp('2012-12-31 00:00:00'), NaT, Timestamp('2012-12-30 00:00:00')]

# timedelta + timedelta -> timedelta
In [106]: tdi + Timedelta('10 days')
Out[106]: TimedeltaIndex(['11 days', NaT, '12 days'], dtype='timedelta64[ns]', freq=None)

# division can result in a Timedelta if the divisor is an integer
In [107]: tdi / 2
Out[107]: TimedeltaIndex(['0 days 12:00:00', NaT, '1 days 00:00:00'], dtype='timedelta64[ns]', freq=None)

# or a Float64Index if the divisor is a Timedelta
In [108]: tdi / tdi[0]
Out[108]: Float64Index([1.0, nan, 2.0], dtype='float64')

Ресемплинг

Аналогично ресемплингу временных рядов, мы можем ресемплировать с TimedeltaIndex.

In [109]: s.resample('D').mean()
Out[109]: 
1 days    11.5
2 days    35.5
3 days    59.5
4 days    83.5
5 days    97.5
Freq: D, dtype: float64

© 2008–2012, AQR Capital Management, LLC, Lambda Foundry, Inc. and PyData Development Team
Licensed under the 3-clause BSD License.
https://pandas.pydata.org/pandas-docs/version/0.19.2/timedeltas.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API