Эта статья приняла участие"Проект "Звезда раскопок"", чтобы выиграть творческий подарочный пакет и бросить вызов творческим поощрительным деньгам
«Добро пожаловать для обсуждения в области комментариев, официальный представитель NuggetsПроект «Звезда раскопок»После мероприятия в комментариях будет разыграно 100 штук Наггетсов.Подробнее о лотерее читайте в статье о мероприятии».
Введение
Время должно быть типом данных, который часто используется при обработке данных.Помимо двух типов данных datetime64 и timedelta64 в Numpy, панды также интегрируют другие библиотеки Python, такие какscikits.timeseries
функция в .
временная классификация
В пандах есть четыре типа времени:
- Дата и время: Дата и время с часовым поясом. и в стандартной библиотеке
datetime.datetime
похожий. - Дельты времени: абсолютная продолжительность и в стандартной библиотеке
datetime.timedelta
похожий. - Промежутки времени: промежутки времени, определяемые временными точками и связанными с ними частотами.
- Смещение даты: время на основе календаря Аналогично dateutil.relativedelta.relativedelta.
Мы используем таблицу для представления:
тип | скалярный класс | класс массива | тип данных панды | основной способ создания |
---|---|---|---|---|
Date times | Timestamp |
DatetimeIndex |
datetime64[ns] or datetime64[ns, tz]
|
to_datetime or date_range
|
Time deltas | Timedelta |
TimedeltaIndex |
timedelta64[ns] |
to_timedelta or timedelta_range
|
Time spans | Period |
PeriodIndex |
period[freq] |
Period or period_range
|
Date offsets | DateOffset |
None |
None |
DateOffset |
См. пример использования:
In [19]: pd.Series(range(3), index=pd.date_range("2000", freq="D", periods=3))
Out[19]:
2000-01-01 0
2000-01-02 1
2000-01-03 2
Freq: D, dtype: int64
Взгляните на нулевое значение типа данных выше:
In [24]: pd.Timestamp(pd.NaT)
Out[24]: NaT
In [25]: pd.Timedelta(pd.NaT)
Out[25]: NaT
In [26]: pd.Period(pd.NaT)
Out[26]: NaT
# Equality acts as np.nan would
In [27]: pd.NaT == pd.NaT
Out[27]: False
Timestamp
Timestamp - самый простой тип времени, мы можем создать это так:
In [28]: pd.Timestamp(datetime.datetime(2012, 5, 1))
Out[28]: Timestamp('2012-05-01 00:00:00')
In [29]: pd.Timestamp("2012-05-01")
Out[29]: Timestamp('2012-05-01 00:00:00')
In [30]: pd.Timestamp(2012, 5, 1)
Out[30]: Timestamp('2012-05-01 00:00:00')
DatetimeIndex
Отметка времени как индекс автоматически преобразуется в DatetimeIndex:
In [33]: dates = [
....: pd.Timestamp("2012-05-01"),
....: pd.Timestamp("2012-05-02"),
....: pd.Timestamp("2012-05-03"),
....: ]
....:
In [34]: ts = pd.Series(np.random.randn(3), dates)
In [35]: type(ts.index)
Out[35]: pandas.core.indexes.datetimes.DatetimeIndex
In [36]: ts.index
Out[36]: DatetimeIndex(['2012-05-01', '2012-05-02', '2012-05-03'], dtype='datetime64[ns]', freq=None)
In [37]: ts
Out[37]:
2012-05-01 0.469112
2012-05-02 -0.282863
2012-05-03 -1.509059
dtype: float64
date_range и bdate_range
Вы также можете использовать date_range для создания DatetimeIndex:
In [74]: start = datetime.datetime(2011, 1, 1)
In [75]: end = datetime.datetime(2012, 1, 1)
In [76]: index = pd.date_range(start, end)
In [77]: index
Out[77]:
DatetimeIndex(['2011-01-01', '2011-01-02', '2011-01-03', '2011-01-04',
'2011-01-05', '2011-01-06', '2011-01-07', '2011-01-08',
'2011-01-09', '2011-01-10',
...
'2011-12-23', '2011-12-24', '2011-12-25', '2011-12-26',
'2011-12-27', '2011-12-28', '2011-12-29', '2011-12-30',
'2011-12-31', '2012-01-01'],
dtype='datetime64[ns]', length=366, freq='D')
date_range
календарный диапазон,bdate_range
диапазон рабочих дней:
In [78]: index = pd.bdate_range(start, end)
In [79]: index
Out[79]:
DatetimeIndex(['2011-01-03', '2011-01-04', '2011-01-05', '2011-01-06',
'2011-01-07', '2011-01-10', '2011-01-11', '2011-01-12',
'2011-01-13', '2011-01-14',
...
'2011-12-19', '2011-12-20', '2011-12-21', '2011-12-22',
'2011-12-23', '2011-12-26', '2011-12-27', '2011-12-28',
'2011-12-29', '2011-12-30'],
dtype='datetime64[ns]', length=260, freq='B')
Оба метода можно использоватьstart
, end
, иperiods
параметр.
In [84]: pd.bdate_range(end=end, periods=20)
In [83]: pd.date_range(start, end, freq="W")
In [86]: pd.date_range("2018-01-01", "2018-01-05", periods=5)
origin
использоватьorigin
параметры, можно изменитьDatetimeIndex
отправная точка:
In [67]: pd.to_datetime([1, 2, 3], unit="D", origin=pd.Timestamp("1960-01-01"))
Out[67]: DatetimeIndex(['1960-01-02', '1960-01-03', '1960-01-04'], dtype='datetime64[ns]', freq=None)
по умолчаниюorigin='unix'
, то есть начальная точка1970-01-01 00:00:00
.
In [68]: pd.to_datetime([1, 2, 3], unit="D")
Out[68]: DatetimeIndex(['1970-01-02', '1970-01-03', '1970-01-04'], dtype='datetime64[ns]', freq=None)
формат
Используйте формат времени параметра формата:
In [51]: pd.to_datetime("2010/11/12", format="%Y/%m/%d")
Out[51]: Timestamp('2010-11-12 00:00:00')
In [52]: pd.to_datetime("12-11-2010 00:00", format="%d-%m-%Y %H:%M")
Out[52]: Timestamp('2010-11-12 00:00:00')
Period
Period представляет промежуток времени, обычно используемый с freq:
In [31]: pd.Period("2011-01")
Out[31]: Period('2011-01', 'M')
In [32]: pd.Period("2012-05", freq="D")
Out[32]: Period('2012-05-01', 'D')
Периодом можно управлять напрямую:
In [345]: p = pd.Period("2012", freq="A-DEC")
In [346]: p + 1
Out[346]: Period('2013', 'A-DEC')
In [347]: p - 3
Out[347]: Period('2009', 'A-DEC')
In [348]: p = pd.Period("2012-01", freq="2M")
In [349]: p + 2
Out[349]: Period('2012-05', '2M')
In [350]: p - 1
Out[350]: Period('2011-11', '2M')
Обратите внимание, что Period может выполнять арифметические действия только в том случае, если он имеет ту же частоту. включая смещения и timedelta
In [352]: p = pd.Period("2014-07-01 09:00", freq="H")
In [353]: p + pd.offsets.Hour(2)
Out[353]: Period('2014-07-01 11:00', 'H')
In [354]: p + datetime.timedelta(minutes=120)
Out[354]: Period('2014-07-01 11:00', 'H')
In [355]: p + np.timedelta64(7200, "s")
Out[355]: Period('2014-07-01 11:00', 'H')
Период как индекс может быть автоматически преобразован в PeriodIndex:
In [38]: periods = [pd.Period("2012-01"), pd.Period("2012-02"), pd.Period("2012-03")]
In [39]: ts = pd.Series(np.random.randn(3), periods)
In [40]: type(ts.index)
Out[40]: pandas.core.indexes.period.PeriodIndex
In [41]: ts.index
Out[41]: PeriodIndex(['2012-01', '2012-02', '2012-03'], dtype='period[M]', freq='M')
In [42]: ts
Out[42]:
2012-01 -1.135632
2012-02 1.212112
2012-03 -0.173215
Freq: M, dtype: float64
PeriodIndex можно создать с помощью метода pd.period_range:
In [359]: prng = pd.period_range("1/1/2011", "1/1/2012", freq="M")
In [360]: prng
Out[360]:
PeriodIndex(['2011-01', '2011-02', '2011-03', '2011-04', '2011-05', '2011-06',
'2011-07', '2011-08', '2011-09', '2011-10', '2011-11', '2011-12',
'2012-01'],
dtype='period[M]', freq='M')
Его также можно создать напрямую через PeriodIndex:
In [361]: pd.PeriodIndex(["2011-1", "2011-2", "2011-3"], freq="M")
Out[361]: PeriodIndex(['2011-01', '2011-02', '2011-03'], dtype='period[M]', freq='M')
DateOffset
DateOffset представляет объект частоты. Он похож на Timedelta тем, что представляет продолжительность, но с особыми календарными правилами. Например, в Timedelta сутки должны быть 24 часа, а в DateOffset, в зависимости от летнего времени, в сутках может быть 23, 24 или 25 часов.
# This particular day contains a day light savings time transition
In [144]: ts = pd.Timestamp("2016-10-30 00:00:00", tz="Europe/Helsinki")
# Respects absolute time
In [145]: ts + pd.Timedelta(days=1)
Out[145]: Timestamp('2016-10-30 23:00:00+0200', tz='Europe/Helsinki')
# Respects calendar time
In [146]: ts + pd.DateOffset(days=1)
Out[146]: Timestamp('2016-10-31 00:00:00+0200', tz='Europe/Helsinki')
In [147]: friday = pd.Timestamp("2018-01-05")
In [148]: friday.day_name()
Out[148]: 'Friday'
# Add 2 business days (Friday --> Tuesday)
In [149]: two_business_days = 2 * pd.offsets.BDay()
In [150]: two_business_days.apply(friday)
Out[150]: Timestamp('2018-01-09 00:00:00')
In [151]: friday + two_business_days
Out[151]: Timestamp('2018-01-09 00:00:00')
In [152]: (friday + two_business_days).day_name()
Out[152]: 'Tuesday'
DateOffsets иFrequencyОперация закрыта первой, взгляните на доступныеDate Offsetсвязанные с нимFrequency:
Date Offset | Frequency String | описывать |
---|---|---|
DateOffset |
None | Общий класс смещения |
BDay or BusinessDay
|
'B' |
рабочий день |
CDay or CustomBusinessDay
|
'C' |
нестандартный рабочий день |
Week |
'W' |
неделя |
WeekOfMonth |
'WOM' |
День недели месяца |
LastWeekOfMonth |
'LWOM' |
День последней недели каждого месяца |
MonthEnd |
'M' |
конец календарного месяца |
MonthBegin | 'MS' |
начало календаря |
BMonthEnd or BusinessMonthEnd
|
'BM' |
конец бизнеса |
BMonthBegin or BusinessMonthBegin
|
'BMS' |
начало бизнеса |
CBMonthEnd or CustomBusinessMonthEnd
|
'CBM' |
Индивидуальный бизнес на конец месяца |
CBMonthBegin or CustomBusinessMonthBegin
|
'CBMS' |
Индивидуальное начало бизнеса |
SemiMonthEnd |
'SM' |
15 число в конце календарного месяца |
SemiMonthBegin |
'SMS' |
15 число первого месяца календаря |
QuarterEnd |
'Q' |
конец календарного квартала |
QuarterBegin |
'QS' |
Календарь |
BQuarterEnd |
'BQ |
конец рабочего сезона |
BQuarterBegin |
'BQS' |
Начало рабочего сезона |
FY5253Quarter |
'REQ' |
Розничный сезон (52-53 неделя) |
YearEnd |
'A' |
конец календарного года |
YearBegin |
'AS' or 'BYS'
|
начало календаря |
BYearEnd |
'BA' |
конец рабочего года |
BYearBegin |
'BAS' |
начало бизнеса |
FY5253 |
'RE' |
Розничный год (он же 52-53 неделя) |
Easter |
None | Пасхальные каникулы |
BusinessHour |
'BH' |
business hour |
CustomBusinessHour |
'CBH' |
custom business hour |
Day |
'D' |
абсолютное время суток |
Hour |
'H' |
Один час |
Minute |
'T' or 'min'
|
Одна минута |
Second |
'S' |
секундочку |
Milli |
'L' or 'ms'
|
Трепет |
Micro |
'U' or 'us'
|
одна миллисекунда |
Nano |
'N' |
одна наносекунда |
DateOffset имеет еще два методаrollforward()
иrollback()
Время можно перемещать:
In [153]: ts = pd.Timestamp("2018-01-06 00:00:00")
In [154]: ts.day_name()
Out[154]: 'Saturday'
# BusinessHour's valid offset dates are Monday through Friday
In [155]: offset = pd.offsets.BusinessHour(start="09:00")
# Bring the date to the closest offset date (Monday)
In [156]: offset.rollforward(ts)
Out[156]: Timestamp('2018-01-08 09:00:00')
# Date is brought to the closest offset date first and then the hour is added
In [157]: ts + offset
Out[157]: Timestamp('2018-01-08 10:00:00')
Вышеупомянутая операция автоматически сохранит часы, минуты и другую информацию.Если вы хотите установить его на 00:00:00, вы можете вызвать метод normalize():
In [158]: ts = pd.Timestamp("2014-01-01 09:00")
In [159]: day = pd.offsets.Day()
In [160]: day.apply(ts)
Out[160]: Timestamp('2014-01-02 09:00:00')
In [161]: day.apply(ts).normalize()
Out[161]: Timestamp('2014-01-02 00:00:00')
In [162]: ts = pd.Timestamp("2014-01-01 22:00")
In [163]: hour = pd.offsets.Hour()
In [164]: hour.apply(ts)
Out[164]: Timestamp('2014-01-01 23:00:00')
In [165]: hour.apply(ts).normalize()
Out[165]: Timestamp('2014-01-01 00:00:00')
In [166]: hour.apply(pd.Timestamp("2014-01-01 23:30")).normalize()
Out[166]: Timestamp('2014-01-02 00:00:00')
как индекс
Время можно использовать в качестве указателя, и когда оно используется в качестве указателя, у него будут очень удобные функции.
Вы можете использовать время напрямую, чтобы получить соответствующие данные:
In [99]: ts["1/31/2011"]
Out[99]: 0.11920871129693428
In [100]: ts[datetime.datetime(2011, 12, 25):]
Out[100]:
2011-12-30 0.56702
Freq: BM, dtype: float64
In [101]: ts["10/31/2011":"12/31/2011"]
Out[101]:
2011-10-31 0.271860
2011-11-30 -0.424972
2011-12-30 0.567020
Freq: BM, dtype: float64
Получить данные за весь год:
In [102]: ts["2011"]
Out[102]:
2011-01-31 0.119209
2011-02-28 -1.044236
2011-03-31 -0.861849
2011-04-29 -2.104569
2011-05-31 -0.494929
2011-06-30 1.071804
2011-07-29 0.721555
2011-08-31 -0.706771
2011-09-30 -1.039575
2011-10-31 0.271860
2011-11-30 -0.424972
2011-12-30 0.567020
Freq: BM, dtype: float64
Получить данные за определенный месяц:
In [103]: ts["2011-6"]
Out[103]:
2011-06-30 1.071804
Freq: BM, dtype: float64
DF может принимать время в качестве аргумента для loc:
In [105]: dft
Out[105]:
A
2013-01-01 00:00:00 0.276232
2013-01-01 00:01:00 -1.087401
2013-01-01 00:02:00 -0.673690
2013-01-01 00:03:00 0.113648
2013-01-01 00:04:00 -1.478427
... ...
2013-03-11 10:35:00 -0.747967
2013-03-11 10:36:00 -0.034523
2013-03-11 10:37:00 -0.201754
2013-03-11 10:38:00 -1.509067
2013-03-11 10:39:00 -1.693043
[100000 rows x 1 columns]
In [106]: dft.loc["2013"]
Out[106]:
A
2013-01-01 00:00:00 0.276232
2013-01-01 00:01:00 -1.087401
2013-01-01 00:02:00 -0.673690
2013-01-01 00:03:00 0.113648
2013-01-01 00:04:00 -1.478427
... ...
2013-03-11 10:35:00 -0.747967
2013-03-11 10:36:00 -0.034523
2013-03-11 10:37:00 -0.201754
2013-03-11 10:38:00 -1.509067
2013-03-11 10:39:00 -1.693043
[100000 rows x 1 columns]
квант времени:
In [107]: dft["2013-1":"2013-2"]
Out[107]:
A
2013-01-01 00:00:00 0.276232
2013-01-01 00:01:00 -1.087401
2013-01-01 00:02:00 -0.673690
2013-01-01 00:03:00 0.113648
2013-01-01 00:04:00 -1.478427
... ...
2013-02-28 23:55:00 0.850929
2013-02-28 23:56:00 0.976712
2013-02-28 23:57:00 -2.693884
2013-02-28 23:58:00 -1.575535
2013-02-28 23:59:00 -1.573517
[84960 rows x 1 columns]
Ломтик и точный матч
Рассмотрим следующий объект Series с дробной точностью:
In [120]: series_minute = pd.Series(
.....: [1, 2, 3],
.....: pd.DatetimeIndex(
.....: ["2011-12-31 23:59:00", "2012-01-01 00:00:00", "2012-01-01 00:02:00"]
.....: ),
.....: )
.....:
In [121]: series_minute.index.resolution
Out[121]: 'minute'
Если точность времени меньше минут, возвращается объект Series:
In [122]: series_minute["2011-12-31 23"]
Out[122]:
2011-12-31 23:59:00 1
dtype: int64
Если точность времени больше минут, возвращается константа:
In [123]: series_minute["2011-12-31 23:59"]
Out[123]: 1
In [124]: series_minute["2011-12-31 23:59:00"]
Out[124]: 1
Точно так же, если точность равна секундам, объект будет возвращен менее чем за секунды, и будет возвращено постоянное значение, если оно равно секундам.
Операции над временными рядами
Shifting
Используйте метод сдвига, чтобы соответствующим образом переместить временной ряд:
In [275]: ts = pd.Series(range(len(rng)), index=rng)
In [276]: ts = ts[:5]
In [277]: ts.shift(1)
Out[277]:
2012-01-01 NaN
2012-01-02 0.0
2012-01-03 1.0
Freq: D, dtype: float64
Указав freq, можно задать способ сдвига:
In [278]: ts.shift(5, freq="D")
Out[278]:
2012-01-06 0
2012-01-07 1
2012-01-08 2
Freq: D, dtype: int64
In [279]: ts.shift(5, freq=pd.offsets.BDay())
Out[279]:
2012-01-06 0
2012-01-09 1
2012-01-10 2
dtype: int64
In [280]: ts.shift(5, freq="BM")
Out[280]:
2012-05-31 0
2012-05-31 1
2012-05-31 2
dtype: int64
преобразование частоты
Временной ряд можно преобразовать в его частоту, вызвав метод asfreq:
In [281]: dr = pd.date_range("1/1/2010", periods=3, freq=3 * pd.offsets.BDay())
In [282]: ts = pd.Series(np.random.randn(3), index=dr)
In [283]: ts
Out[283]:
2010-01-01 1.494522
2010-01-06 -0.778425
2010-01-11 -0.253355
Freq: 3B, dtype: float64
In [284]: ts.asfreq(pd.offsets.BDay())
Out[284]:
2010-01-01 1.494522
2010-01-04 NaN
2010-01-05 NaN
2010-01-06 -0.778425
2010-01-07 NaN
2010-01-08 NaN
2010-01-11 -0.253355
Freq: B, dtype: float64
asfreq также может указать метод заполнения после изменения частоты:
In [285]: ts.asfreq(pd.offsets.BDay(), method="pad")
Out[285]:
2010-01-01 1.494522
2010-01-04 1.494522
2010-01-05 1.494522
2010-01-06 -0.778425
2010-01-07 -0.778425
2010-01-08 -0.778425
2010-01-11 -0.253355
Freq: B, dtype: float64
передискретизация
Данная последовательность времени может быть повторной выборки путем вызова метода повторной доступности:
In [286]: rng = pd.date_range("1/1/2012", periods=100, freq="S")
In [287]: ts = pd.Series(np.random.randint(0, 500, len(rng)), index=rng)
In [288]: ts.resample("5Min").sum()
Out[288]:
2012-01-01 25103
Freq: 5T, dtype: int64
Resample может принимать различные статистические методы, такие как:sum
, mean
, std
, sem
, max
, min
, median
, first
, last
, ohlc
.
In [289]: ts.resample("5Min").mean()
Out[289]:
2012-01-01 251.03
Freq: 5T, dtype: float64
In [290]: ts.resample("5Min").ohlc()
Out[290]:
open high low close
2012-01-01 308 460 9 205
In [291]: ts.resample("5Min").max()
Out[291]:
2012-01-01 460
Freq: 5T, dtype: int64
Эта статья была включена вwoohoo.floydpress.com/15-python-afraid…
Самая популярная интерпретация, самая глубокая галантерея, самые краткие уроки и множество трюков, о которых вы не знаете, ждут вас!
Добро пожаловать, чтобы обратить внимание на мой официальный аккаунт: «Программируйте эти вещи», разбирайтесь в технологиях, лучше поймите себя!