«Это 27-й день моего участия в ноябрьском испытании обновлений. Подробную информацию об этом событии см.:Вызов последнего обновления 2021 г."
Индекс отметки времени Pandas — DatetimeIndex
pd.DatetimeIndex() с временными рядами TimeSeries
pd.DatetimeIndex()
Индексы временных меток могут быть сгенерированы напрямую, и поддерживаются str, datetime.datetime.
Одна временная метка имеет типTimestamp
, несколько меток времени имеют типDatetimeIndex
, пример следующий:
rng = pd.DatetimeIndex(['12/1/2017','12/2/2017','12/3/2017','12/4/2017','12/5/2017'])
print(rng,type(rng))
print(rng[0],type(rng[0]))
>>>
DatetimeIndex(['2017-12-01', '2017-12-02', '2017-12-03', '2017-12-04',
'2017-12-05'],
dtype='datetime64[ns]', freq=None) <class 'pandas.core.indexes.datetimes.DatetimeIndex'>
2017-12-01 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>
Что такое временной ряд TimeSeries?
отDatetimeIndex
Серия индекса, временной ряд TimeSries
Возьмите каштан:
st = pd.Series(np.random.rand(len(rng)), index = rng)
print(st,type(st))
print(st.index)
>>>
2017-12-01 0.081920
2017-12-02 0.921781
2017-12-03 0.489779
2017-12-04 0.257632
2017-12-05 0.805373
dtype: float64 <class 'pandas.core.series.Series'>
DatetimeIndex(['2017-12-01', '2017-12-02', '2017-12-03', '2017-12-04',
'2017-12-05'],
dtype='datetime64[ns]', freq=None)
pd.date_range() — генерирует диапазон дат
pd.date_range() генерирует диапазоны дат двумя способами (частота по умолчанию — день):
- время начала (начало) + время окончания (конец)
- время начала (начало)/время окончания (конец) + смещение (периоды)
Возьмите каштан:
date1 = pd.date_range('2017/1/1','2017/10/1',normalize=True)
print(date1)
date2 = pd.date_range(start = '1/1/2017', periods = 10)
print(date2)
date3 = pd.date_range(end = '1/30/2017 15:00:00', periods = 10,normalize=True) # 增加了时、分、秒
print(date3)
>>>
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
'2017-01-05', '2017-01-06', '2017-01-07', '2017-01-08',
'2017-01-09', '2017-01-10',
...
'2017-09-22', '2017-09-23', '2017-09-24', '2017-09-25',
'2017-09-26', '2017-09-27', '2017-09-28', '2017-09-29',
'2017-09-30', '2017-10-01'],
dtype='datetime64[ns]', length=274, freq='D')
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
'2017-01-05', '2017-01-06', '2017-01-07', '2017-01-08',
'2017-01-09', '2017-01-10'],
dtype='datetime64[ns]', freq='D')
DatetimeIndex(['2017-01-21', '2017-01-22', '2017-01-23', '2017-01-24',
'2017-01-25', '2017-01-26', '2017-01-27', '2017-01-28',
'2017-01-29', '2017-01-30'],
dtype='datetime64[ns]', freq='D')
pd.date_range(start=None, end=None, periods=None, freq='D', tz=None, normalize=False, name=None, closed=None, **kwargs)
Обычно используемые параметры имеют следующие значения:
- начало: время начала
- конец: время окончания
- периоды: смещение
- freq: частота, день по умолчанию, частота pd.date_range() по умолчанию — календарный день, частота pd.bdate_range() по умолчанию — рабочий день
- тц: часовой пояс
- normalize: значения параметров времени нормализуются до полуночных временных меток.
- закрыто: когда по умолчанию установлено значение «Нет», левое закрыто, а правое закрыто, левое — левое закрыто, а правое — открыто, а правое — левое открыто и правое закрыто.
дать каштановую паруnormalize
Практическое использование параметров:
rng4 = pd.date_range(start = '1/1/2017 15:30', periods = 10, name = 'hello world!', normalize = True)
print(rng4)
>>>
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
'2017-01-05', '2017-01-06', '2017-01-07', '2017-01-08',
'2017-01-09', '2017-01-10'],
dtype='datetime64[ns]', name='hello world!', freq='D')
Use of freq (1) — Генерация временных рядов с фиксированной частотой
Основное использование заключается в следующем:
print(pd.date_range('2017/1/1','2017/1/4')) # 默认freq = 'D':每日历日
print(pd.date_range('2017/1/1','2017/1/4', freq = 'B')) # B:每工作日
print(pd.date_range('2017/1/1','2017/1/2', freq = 'H')) # H:每小时
print(pd.date_range('2017/1/1 12:00','2017/1/1 12:10', freq = 'T')) # T/MIN:每分
print(pd.date_range('2017/1/1 12:00:00','2017/1/1 12:00:10', freq = 'S')) # S:每秒
print(pd.date_range('2017/1/1 12:00:00','2017/1/1 12:00:10', freq = 'L')) # L:每毫秒(千分之一秒)
print(pd.date_range('2017/1/1 12:00:00','2017/1/1 12:00:10', freq = 'U')) # U:每微秒(百万分之一秒)
Расширенное использование заключается в следующем:
print(pd.date_range('2017/1/1','2017/2/1', freq = 'W-MON'))
# W-MON:从指定星期几开始算起,每周
# 星期几缩写:MON/TUE/WED/THU/FRI/SAT/SUN
print(pd.date_range('2017/1/1','2017/5/1', freq = 'WOM-2MON'))
# WOM-2MON:每月的第几个星期几开始算,这里是每月第二个星期一
Использование частоты (2) - временной ряд, необходимый для диверсифицированной генерации
Сгенерировать календарные дни с заданной периодичностью:
print(pd.date_range('2017','2018', freq = 'M'))
print(pd.date_range('2017','2020', freq = 'Q-DEC'))
print(pd.date_range('2017','2020', freq = 'A-DEC'))
print('------')
# M:每月最后一个日历日
# Q-月:指定月为季度末,每个季度末最后一月的最后一个日历日
# A-月:每年指定月份的最后一个日历日
# 月缩写:JAN/FEB/MAR/APR/MAY/JUN/JUL/AUG/SEP/OCT/NOV/DEC
# 所以Q-月只有三种情况:1-4-7-10,2-5-8-11,3-6-9-12
Сгенерировать дни недели с заданной периодичностью:
print(pd.date_range('2017','2018', freq = 'BM'))
print(pd.date_range('2017','2020', freq = 'BQ-DEC'))
print(pd.date_range('2017','2020', freq = 'BA-DEC'))
print('------')
# BM:每月最后一个工作日
# BQ-月:指定月为季度末,每个季度末最后一月的最后一个工作日
# BA-月:每年指定月份的最后一个工作日
Создайте специальное время для указанного шаблона:
print(pd.date_range('2017','2018', freq = 'MS'))
print(pd.date_range('2017','2020', freq = 'QS-DEC'))
print(pd.date_range('2017','2020', freq = 'AS-DEC'))
print('------')
# M:每月第一个日历日
# QS-月:指定月为季度末,每个季度末最后一月的第一个日历日
# AS-月:每年指定月份的第一个日历日
print(pd.date_range('2017','2018', freq = 'BMS'))
print(pd.date_range('2017','2020', freq = 'BQS-DEC'))
print(pd.date_range('2017','2020', freq = 'BAS-DEC'))
print('------')
# BMS:每月第一个工作日
# BQS-月:指定月为季度末,每个季度末最后一月的第一个工作日
# BAS-月:每年指定月份的第一个工作日
Use of freq (3) — Использование составных частот
Создайте временной ряд с заданными составными частотами:
print(pd.date_range('2017/1/1','2017/2/1', freq = '7D')) # 7天
print(pd.date_range('2017/1/1','2017/1/2', freq = '2h30min')) # 2小时30分钟
print(pd.date_range('2017','2018', freq = '2M')) # 每间隔2个月的第一个日历日
asfreq - преобразование частоты эпохи
Как можно преобразовать временной ряд с частотой дневного интервала во временной ряд с меньшим единичным интервалом?
ts = pd.Series(np.random.rand(4),
index = pd.date_range('20170101','20170104'))
print(ts)
print(ts.asfreq('4H',method = 'ffill'))
# 改变频率,这里是D改为4H
# method:插值模式,None不插值,ffill用之前值填充,bfill用之后值填充
Как опережать/отставать данные?
Следующие каштановые сдвиги данных опережения/отставания являются числовыми значениями:
ts = pd.Series(np.random.rand(4),
index = pd.date_range('20170101','20170104'))
print(ts)
print(ts.shift(2))
print(ts.shift(-2))
print('------')
# 正数:数值后移(滞后);负数:数值前移(超前)
>>>
2017-01-01 0.575076
2017-01-02 0.514981
2017-01-03 0.221506
2017-01-04 0.410396
Freq: D, dtype: float64
2017-01-01 NaN
2017-01-02 NaN
2017-01-03 0.575076
2017-01-04 0.514981
Freq: D, dtype: float64
2017-01-01 0.221506
2017-01-02 0.410396
2017-01-03 NaN
2017-01-04 NaN
Freq: D, dtype: float64
Добавление параметра смещения частоты смещает предыдущую отметку времени индекса вместо значения:
print(ts.shift(2, freq = 'D'))
print(ts.shift(2, freq = 'T'))
# 加上freq参数:对时间戳进行位移,而不是对数值进行位移
Панды Период - Период
pd.Period() период создания
Создайте конструктор времени с месячной периодичностью, начиная с 2017-01:
p = pd.Period('2017', freq = 'M')
print(p, type(p))
>>>
2017-01 <class 'pandas._period.Period'>
Мы можем перемещать период целиком, добавляя и вычитая целые числа:
p = pd.Period('2017', freq = 'M')
print(p, type(p))
print(p + 1)
print(p - 2)
>>>
2017-02
2016-11
pd.period_range() создает диапазон периодов
Создайте указанный диапазон периодов:
prng = pd.period_range('1/1/2011', '1/1/2012', freq='M')
print(prng,type(prng))
>>>
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='int64', freq='M') <class 'pandas.tseries.period.PeriodIndex'>
Объедините вышеуказанные ряды периодов, чтобы создать временной ряд:
ts = pd.Series(np.random.rand(len(prng)), index = prng)
print(ts,type(ts))
print(ts.index)
>>>
2011-01 0.342571
2011-02 0.826151
2011-03 0.370505
2011-04 0.137151
2011-05 0.679976
2011-06 0.265928
2011-07 0.416502
2011-08 0.874078
2011-09 0.112801
2011-10 0.112504
2011-11 0.448408
2011-12 0.851046
2012-01 0.370605
Freq: M, dtype: float64 <class 'pandas.core.series.Series'>
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='int64', freq='M')
pd.period - asfreq: преобразование частоты
Ранее сгенерированные частоты могут быть преобразованы в другие частоты методом .asfreq(freq, method=None, how=None)
p = pd.Period('2017','A-DEC')
print(p)
print(p.asfreq('M', how = 'start')) # 也可写 how = 's'
print(p.asfreq('D', how = 'end')) # 也可写 how = 'e'
>>>
2017
2017-01
2017-12-31
asfreq также может преобразовать индекс TIMESeries:
prng = pd.period_range('2017','2018',freq = 'M')
ts1 = pd.Series(np.random.rand(len(prng)), index = prng)
ts2 = pd.Series(np.random.rand(len(prng)), index = prng.asfreq('D', how = 'start'))
print(ts1.head(),len(ts1))
print(ts2.head(),len(ts2))
Преобразование между отметкой времени и эпохой
Используйте pd.to_period(), pd.to_timestamp() для преобразования между метками времени и периодами.
rng = pd.date_range('2017/1/1', periods = 10, freq = 'M')
prng = pd.period_range('2017','2018', freq = 'M')
ts1 = pd.Series(np.random.rand(len(rng)), index = rng)
print(ts1.head())
print(ts1.to_period().head())
# 每月最后一日,转化为每月
ts2 = pd.Series(np.random.rand(len(prng)), index = prng)
print(ts2.head())
print(ts2.to_timestamp().head())
# 每月,转化为每月第一天
>>>
2017-01-31 0.125288
2017-02-28 0.497174
2017-03-31 0.573114
2017-04-30 0.665665
2017-05-31 0.263561
Freq: M, dtype: float64
2017-01 0.125288
2017-02 0.497174
2017-03 0.573114
2017-04 0.665665
2017-05 0.263561
Freq: M, dtype: float64
2017-01 0.748661
2017-02 0.095891
2017-03 0.280341
2017-04 0.569813
2017-05 0.067677
Freq: M, dtype: float64
2017-01-01 0.748661
2017-02-01 0.095891
2017-03-01 0.280341
2017-04-01 0.569813
2017-05-01 0.067677
Freq: MS, dtype: float64
Индексирование и нарезка временных рядов
показатель
Метод индексации временных рядов также применим к Dataframe, а во временном ряду, поскольку он сортируется по временной последовательности, нет необходимости рассматривать проблему порядка.
Индекс базовой позиции с использованием методов, аналогичных спискам:
from datetime import datetime
rng = pd.date_range('2017/1','2017/3')
ts = pd.Series(np.random.rand(len(rng)), index = rng)
print(ts.head())
print(ts[0])
print(ts[:2])
>>>
2017-01-01 0.107736
2017-01-02 0.887981
2017-01-03 0.712862
2017-01-04 0.920021
2017-01-05 0.317863
Freq: D, dtype: float64
0.107735945027
2017-01-01 0.107736
2017-01-02 0.887981
Freq: D, dtype: float64
В дополнение к базовому индексу позиции есть индекс метки временного ряда:
from datetime import datetime
rng = pd.date_range('2017/1','2017/3')
ts = pd.Series(np.random.rand(len(rng)), index = rng)
print(ts['2017/1/2'])
print(ts['20170103'])
print(ts['1/10/2017'])
print(ts[datetime(2017,1,20)])
>>>
0.887980757812
0.712861778966
0.788336674948
0.93070380011
кусочек
Использование срезов упоминается в индексе базовой позиции раздела индекса выше, что совпадает с принципом индекса индекса Series, и он также включен в конец.
rng = pd.date_range('2017/1','2017/3',freq = '12H')
ts = pd.Series(np.random.rand(len(rng)), index = rng)
print(ts['2017/1/5':'2017/1/10'])
>>>
2017-01-05 00:00:00 0.462085
2017-01-05 12:00:00 0.778637
2017-01-06 00:00:00 0.356306
2017-01-06 12:00:00 0.667964
2017-01-07 00:00:00 0.246857
2017-01-07 12:00:00 0.386956
2017-01-08 00:00:00 0.328203
2017-01-08 12:00:00 0.260853
2017-01-09 00:00:00 0.224920
2017-01-09 12:00:00 0.397457
2017-01-10 00:00:00 0.158729
2017-01-10 12:00:00 0.501266
Freq: 12H, dtype: float64
# 在这里我们可以传入月份可以直接获取整个月份的切片
print(ts['2017/2'].head())
>>>
2017-02-01 00:00:00 0.243932
2017-02-01 12:00:00 0.220830
2017-02-02 00:00:00 0.896107
2017-02-02 12:00:00 0.476584
2017-02-03 00:00:00 0.515817
Freq: 12H, dtype: float64
Повторяющиеся индексированные временные ряды
dates = pd.DatetimeIndex(['1/1/2015','1/2/2015','1/3/2015','1/4/2015','1/1/2015','1/2/2015'])
ts = pd.Series(np.random.rand(6), index = dates)
print(ts)
# 我们可以通过is_unique检查值或index是否重复
print(ts.is_unique,ts.index.is_unique)
>>>
2015-01-01 0.300286
2015-01-02 0.603865
2015-01-03 0.017949
2015-01-04 0.026621
2015-01-01 0.791441
2015-01-02 0.526622
dtype: float64
True False
Согласно приведенным выше результатам видно, что в приведенном выше временном ряду индекс (ts.index.is_unique) повторяется, но значение (ts.is_unique) не повторяется.
Мы можем решить проблему дублирования индексов, усредняя значения, соответствующие дублирующимся индексам, по временным рядам:
print(ts.groupby(level = 0).mean())
# 通过groupby做分组,重复的值这里用平均值处理
>>>
2015-01-01 0.545863
2015-01-02 0.565244
2015-01-03 0.017949
2015-01-04 0.026621
dtype: float64