1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/it-ebooks-pyda-2e-zh

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
11.md 25 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 28.11.2024 16:49 0ce2ae9

Время как тип данных в Python

Время — это важный тип структурированных данных, который используется во многих областях, таких как финансы, экономика, экология, нейронаука, физика и другие. Время может быть представлено в виде временных рядов — последовательностей значений, упорядоченных по времени. Временные ряды могут иметь фиксированную частоту (например, данные собираются каждые 15 секунд или каждый месяц) или нефиксированную (без определённой периодичности).

В этой главе рассматриваются три основных типа временных рядов:

  • время (timestamp) — конкретный момент времени;
  • фиксированный период (period) — например, январь 2007 года или весь 2010 год;
  • временной интервал (interval), который определяется начальной и конечной точками времени. Период (period) можно рассматривать как частный случай интервала.

Для обработки экспериментальных временных рядов можно использовать различные методы и алгоритмы. Индексом временного ряда может быть целое число или число с плавающей точкой, которое представляет количество времени, прошедшего с начала эксперимента. Наиболее распространённым типом временного ряда является индекс, основанный на времени (timestamp).

Библиотека Pandas предоставляет множество инструментов для работы с временными рядами, включая функции для индексации, нарезки, агрегации и передискретизации данных. Эти инструменты особенно полезны для финансовых и экономических приложений, а также для анализа серверных журналов.

Работа с датой и временем в Python

Python включает стандартные типы данных для работы с датой (date) и временем (time), а также функции для работы с календарём. Наиболее часто используемый тип данных — datetime, который позволяет хранить дату и время с точностью до миллисекунд.

Тип данных timedelta используется для представления разницы между двумя объектами datetime. Он может быть добавлен или вычтен из объекта datetime для создания нового объекта с изменённой датой или временем.

Модуль datetime содержит несколько типов данных, которые используются для работы со временем. В таблице 11-1 представлены основные типы данных модуля datetime.

Объекты datetime и pandas Timestamp могут быть преобразованы в строки с использованием методов str или strftime. Метод strptime позволяет преобразовать строку в объект datetime с помощью форматирования.

Pandas также предоставляет функцию to_datetime, которая может анализировать различные форматы даты и времени и создавать объекты datetime или временные индексы. Перевод текста на русский язык:

Начальные и конечные даты определяют строгие границы индекса дат. Например, если вы хотите создать индекс дат, состоящий из последнего рабочего дня каждого месяца, вы можете передать частоту «BM» (business end of month), которая будет включать только те даты в интервале (или точно на границе), которые соответствуют требованиям частоты:

In [78]: pd.date_range('2000-01-01', '2000-12-01', freq='BM')
Out[78]: 
DatetimeIndex(['2000-01-31', '2000-02-29', '2000-03-31', '2000-04-28',
               '2000-05-31', '2000-06-30', '2000-07-31', '2000-08-31',
               '2000-09-29', '2000-10-31', '2000-11-30'],
              dtype='datetime64[ns]', freq='BM')

По умолчанию date_range сохраняет информацию о времени начала и окончания времени (если она есть):

In [79]: pd.date_range('2012-05-02 12:56:31', periods=5)
Out[79]: 
DatetimeIndex(['2012-05-02 12:56:31', '2012-05-03 12:56:31',
               '2012-05-04 12:56:31', '2012-05-05 12:56:31',
               '2012-05-06 12:56:31'],
              dtype='datetime64[ns]', freq='D')

Иногда, хотя начальные и конечные даты содержат информацию о времени, вы хотите получить набор временных меток, нормализованных до полуночи. Нормализация может быть достигнута с помощью опции normalize:

In [80]: pd.date_range('2012-05-02 12:56:31', periods=5, normalize=True)
Out[80]: 
DatetimeIndex(['2012-05-02', '2012-05-03', '2012-05-04', '2012-05-05',
               '2012-05-06'],
              dtype='datetime64[ns]', freq='D')

Частота и смещение даты

Частота в pandas состоит из базовой частоты и множителя. Базовая частота обычно представлена в виде строкового псевдонима, например, «M» для месяца или «H» для часа. Для каждой базовой частоты существует соответствующий объект, называемый смещением даты:

In [81]: from pandas.tseries.offsets import Hour, Minute

In [82]: hour = Hour()

In [83]: hour
Out[83]: <Hour>

Передавая целое число, можно определить кратное смещение:

In [84]: four_hours = Hour(4)

In [85]: four_hours
Out[85]: <4 * Hours>

Как правило, нет необходимости явно создавать такие объекты, достаточно использовать псевдонимы строк, такие как «H» или «4H». Вы можете создать кратные, поставив перед базовой частотой целое число:

In [86]: pd.date_range('2000-01-01', '2000-01-03 23:59', freq='4h')
Out[86]: 
DatetimeIndex(['2000-01-01 00:00:00', '2000-01-01 04:00:00',
               '2000-01-01 08:00:00', '2000-01-01 12:00:00',
               '2000-01-01 16:00:00', '2000-01-01 20:00:00',
               '2000-01-02 00:00:00', '2000-01-02 04:00:00',
               '2000-01-02 08:00:00', '2000-01-02 12:00:00',
               '2000-01-02 16:00:00', '2000-01-02 20:00:00',
               '2000-01-03 00:00:00', '2000-01-03 04:00:00',
               '2000-01-03 08:00:00', '2000-01-03 12:00:00',
               '2000-01-03 16:00:00', '2000-01-03 20:00:00'],
              dtype='datetime64[ns]', freq='4H')

Большинство объектов смещения даты могут быть соединены с помощью сложения:

In [87]: Hour(2) + Minute(30)
Out[87]: <150 * Minutes>

Аналогично, вы также можете передать строку частоты («2h30min»), которая может быть эффективно проанализирована в эквивалентное выражение:

In [88]: pd.date_range('2000-01-01', periods=10, freq='1h30min')
Out[88]: 
DatetimeIndex(['2000-01-01 00:00:00', '2000-01-01 01:30:00',
               '2000-01-01 03:00:00', '2000-01-01 04:30:00',
               '2000-01-01 06:00:00', '2000-01-01 07:30:00',
               '2000-01-01 09:00:00', '2000-01-01 10:30:00',
               '2000-01-01 12:00:00', '2000-01-01 13:30:00'],
              dtype='datetime64[ns]', freq='90T')

Некоторые частоты описывают временные точки, которые не равномерно разделены. Например, «M» (последний день месяца) и «BM» (последний рабочий день каждого месяца) зависят от количества дней в месяце, а для последнего также необходимо учитывать, является ли конец месяца выходным днём. Поскольку нет лучшего термина, я называю их привязанными смещениями.

Таблица 11–4 перечисляет коды частот и классы смещения дат в pandas.

Примечание: пользователи могут настраивать некоторые классы частот для предоставления логики дат, отсутствующей в pandas, но конкретные детали выходят за рамки этой книги. Период «2007» с частотой «A-DEC».

Примечание: перевод выполнен автоматически, возможны неточности.

Перевод кода на русский язык:

In [160]: p = pd.Period('2007', freq='A-DEC')

In [161]: p
Out[161]: Period('2007', 'A-DEC')``` **2000-01-30    0.423331**
**2000-01-31   -0.654040**
**2000-02-01    2.089154**
**2000-02-02   -0.060220**
**2000-02-03   -0.167933**

Freq: D, dtype: float64

**В запросе представлен фрагмент кода на языке Python, который используется в библиотеке Pandas для работы с данными.**

В этом фрагменте кода создаются два массива данных с информацией о годе и квартале, которые затем объединяются в один индекс PeriodIndex. Это позволяет объединить данные в единый DataFrame с индексом, содержащим информацию о дате.

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

*Этот фрагмент не содержит технических терминов или специфической информации о разработке программного обеспечения.* ```
ts.resample('M', kind='period').mean()
Out[222]: 
2000-01   -0.165893
2000-02    0.078606
2000-03    0.223811
2000-04   -0.063643
Freq: M, dtype: float64

В этом фрагменте кода используется метод resample для обработки временных рядов. Метод resample позволяет изменять частоту данных временного ряда. В данном случае временной ряд агрегируется до ежемесячной частоты ('M').

Метод mean применяется к агрегированным данным для вычисления среднего значения за каждый месяц. Результатом является серия с индексом в виде дат и значениями в виде средних значений за соответствующий месяц. ``` frame.resample('D').ffill() Out[235]: Colorado Texas New York Ohio 2000-01-05 -0,896431 0,677263 0,036503 0,087102 2000-01-06 -0,896431 0,677263 0,036503 0,087102 2000-01-07 -0,896431 0,677263 0,036503 0,087102 2000-01-08 -0,896431 0,677263 0,036503 0,087102 2000-01-09 -0,896431 0,677263 0,036503 0,087102 2000-01-10 -0,896431 0,677263 0,036503 0,087102 2000-01-11 -0,896431 0,677263 0,036503 0,087102 2000-01-12 -0,046662 0,927238 0,482284 -0,867130


Также можно заполнить только указанный период времени, чтобы ограничить использование предыдущих наблюдений:
```python
In [236]: frame.resample('D').ffill(limit=2)
Out[236]:
            Colorado     Texas  New York      Ohio
2000-01-05 -0,896431  0,677263  0,036503  0,087102
2000-01-06 -0,896431  0,677263  0,036503  0,087102
2000-01-07 -0,896431  0,677263  0,036503  0,087102
2000-01-08 NaN NaN NaN NaN
2000-01-09 NaN NaN NaN NaN
2000-01-10 NaN NaN NaN NaN
2000-01-11 NaN NaN NaN NaN
2000-01-12 -0,046662  0,927238  0,482284 -0,867130

Обратите внимание, что новый индекс даты может не совпадать со старым:

In [237]: frame.resample('W-THU').ffill()
Out[237]: 
            Colorado     Texas  New York      Ohio
2000-01-06 -0,896431  0,677263  0,036503  0,087102
2000-01-13 -0,046662  0,927238  0,482284 -0,867130
``` Данный текст представляет собой фрагмент технической документации, в которой описывается использование функций для работы с временными рядами в библиотеке Pandas на языке Python.

В тексте рассматриваются функции для вычисления скользящих средних значений и других статистических показателей временных рядов. В частности, описываются функции rolling(), expand(), ewma() и их применение для анализа финансовых данных.

**Перевод текста:**

Теперь мы введём оператор rolling, который похож на resample и groupby. Его можно вызвать для TimeSeries или DataFrame, а также для окна, представляющего собой период времени (см. рисунок 11-4):
```python
In [238]: close_px.AAPL.plot()
Out[238]: <matplotlib.axes._subplots.AxesSubplot at 0x7f2f2570cf98>

In [239]: close_px.AAPL.rolling(250).mean().plot()

Выражение rolling(250) похоже на groupby, но вместо того чтобы группировать данные, оно создаёт объект скользящего окна с размером группы 250 дней. Затем мы получаем скользящее среднее значение цены акций компании Apple за 250 дней.

По умолчанию функция rolling требует, чтобы все значения в окне были не равны NA. Это поведение можно изменить, чтобы решить проблему недостающих данных. На самом деле, данные в начале временного ряда, где окно ещё не достигло своего размера, являются особым случаем (см. рисунок 11-5):

In [241]: appl_std250 = close_px.AAPL.rolling(250, min_periods=10).std()

In [242]: appl_std250[5:12]
Out[242]: 
2003-01-09         NaN
2003-01-10         NaN
2003-01-13         NaN
2003-01-14         NaN
2003-01-15    0.077496
2003-01-16    0.074760
2003-01-17    0.112368
Freq: B, Name: AAPL, dtype: float64

In [243]: appl_std250.plot()

Чтобы вычислить расширенное скользящее среднее (expanding window mean), можно использовать expanding вместо rolling. «Расширение» означает, что окно начинается с начала временного ряда и увеличивается до тех пор, пока не превысит всю последовательность. Расширенное скользящее среднее для временного ряда apple_std250 выглядит следующим образом:

In [244]: expanding_mean = appl_std250.expanding().mean()

Вызов rolling_mean для DataFrame применяет преобразование ко всем столбцам (см. рисунок 11-6):

In [246]: close_px.rolling(60).mean().plot(logy=True)

Функция rolling также может принимать фиксированный размер временной компенсации в виде строки, а не набора периодов. Это удобно для обработки нерегулярных временных рядов. Эти строки также могут быть переданы в resample. Например, мы можем вычислить скользящее среднее за 20 дней:

In [247]: close_px.rolling('20D').mean()
Out[247]:
                  AAPL       MSFT        XOM
2003-01-02    7.400000  21.110000  29.220000
2003-01-03    7.425000  21.125000  29.230000
...
2011-10-03  398.002143  25.890714  72.413571
2011-10-04  396.802143  25.807857  72.427143
2011-10-05  395.751429  25.729286  72.422857
...
[2292 rows x 3 columns]

Экспоненциально взвешенные функции

Другой способ использования окон фиксированного размера с равными весами для наблюдений — это определение коэффициента затухания (decay factor), чтобы недавние наблюдения имели больший вес. Существует множество способов определения коэффициента затухания, и один из наиболее распространённых — использование интервала времени (span), который позволяет результатам быть совместимыми с простым скользящим окном (simple moving window) функции, равным интервалу времени.

Поскольку экспоненциальное взвешивание присваивает больший вес недавним наблюдениям, оно может «адаптироваться» к изменениям быстрее, чем равноправное статистическое взвешивание.

Помимо rolling и expanding, pandas также имеет оператор ewm. Следующий пример сравнивает 30-дневное простое скользящее среднее цены акций Apple и 30-дневный интервал времени экспоненциального скользящего среднего (как показано на рисунке 11-7):

In [249]: aapl_px = close_px.AAPL['2006':'2007']

In [250]: ma60 = aapl_px.rolling(30, min_periods=20).mean()

In [251]: ewma60 = aapl_px.ewm(span=30).mean()

In [252]: ma60.plot(style='k--', label='Simple MA')
Out[252]: <matplotlib.axes._subplots.AxesSubplot at 0x7f2f252161d0>

In [253]: ewma60.plot(style='k-', label='EW MA')
Out[253]: <matplotlib.axes._subplots.AxesSubplot at 0x7f2f252161d0>

In [254]: plt.legend()

Рисунок 11–7: Простое скользящее среднее и экспоненциально взвешенное скользящее среднее

Бинарные скользящие оконные функции

Некоторые статистические операции (например, корреляция и ковариация) требуют выполнения на двух временных рядах. Например, финансовые аналитики часто интересуются корреляцией между ценой акций определённой компании и некоторым эталонным индексом (таким как S&P 500). Чтобы проиллюстрировать это, сначала мы вычислим процентное изменение интересующего нас временного ряда:

In [256]: spx_px = close_px_all['SPX']

In [257]: spx_rets = spx_px.pct_change()

In [258]: returns = close_px.pct_change()

После вызова rolling корреляционная агрегатная функция начинает вычислять корреляцию скользящего окна AAPL с spx_rets (результаты показаны на рисунке 11-8):

In [259]: corr = returns.AAPL.rolling(125, min_periods=100).corr(spx_rets)

In [260]: corr.plot()

Рисунок 11–8: Корреляция доходности AAPL за шесть месяцев с доходностью S&P 500 Предположим, вы хотите однократно вычислить коэффициент корреляции между несколькими акциями и индексом S&P 500. Хотя написать цикл и создать новый DataFrame не так сложно, это довольно утомительно. На самом деле нужно только передать TimeSeries и DataFrame в функцию rolling_corr, которая автоматически вычислит коэффициент корреляции TimeSeries (в данном случае spx_rets) с каждой колонкой DataFrame. Результат показан на рисунке 11-9:

In [262]: corr = returns.rolling(125, min_periods=100).corr(spx_rets)

In [263]: corr.plot()

Рисунок 11–9. Коэффициент корреляции доходности трёх акций и индекса S&P 500 за шесть месяцев

Пользовательская функция скользящего окна

Функция rolling_apply позволяет применять пользовательские функции к данным в скользящем окне. Единственное требование — функция должна возвращать единственное значение для каждого фрагмента массива (то есть «сжимать» данные). Например, при использовании rolling(...).quantile(q) для вычисления квантилей выборки может быть интересно узнать процентное содержание определённых значений в выборке. Для этого можно использовать функцию scipy.stats.percentileofscore (результат показан на рисунке 11-10):

In [265]: from scipy.stats import percentileofscore

In [266]: score_at_2percent = lambda x: percentileofscore(x, 0.02)

In [267]: result = returns.AAPL.rolling(250).apply(score_at_2percent)

In [268]: result.plot()

Рисунок 11–10. Процентное содержание доходности AAPL на уровне 2% (годовое окно)

Если у вас не установлен SciPy, его можно установить с помощью conda или pip.

11.8 Заключение

По сравнению с данными из предыдущих разделов, анализ временных рядов требует других инструментов анализа и преобразования данных.

В следующих разделах мы изучим более продвинутые методы pandas и начнём использовать библиотеки моделирования statsmodels и scikit-learn.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/it-ebooks-pyda-2e-zh.git
git@api.gitlife.ru:oschina-mirror/it-ebooks-pyda-2e-zh.git
oschina-mirror
it-ebooks-pyda-2e-zh
it-ebooks-pyda-2e-zh
master