Операции окон#
pandas содержит компактный набор API для выполнения операций скользящего окна - операций, которые выполняют
агрегацию по скользящему разделу значений. API работает аналогично groupby API
в том, что Series и DataFrame вызовите метод оконного преобразования с
необходимыми параметрами, а затем вызовите функцию агрегации.
In [1]: s = pd.Series(range(5))
In [2]: s.rolling(window=2).sum()
Out[2]:
0 NaN
1 1.0
2 3.0
3 5.0
4 7.0
dtype: float64
Окна формируются путем просмотра назад на длину окна от текущего наблюдения. Приведенный выше результат можно получить, взяв сумму следующих оконных разделов данных:
In [3]: for window in s.rolling(window=2):
...: print(window)
...:
0 0
dtype: int64
0 0
1 1
dtype: int64
1 1
2 2
dtype: int64
2 2
3 3
dtype: int64
3 3
4 4
dtype: int64
Обзор#
pandas поддерживает 4 типа оконных операций:
Скользящее окно: Общее фиксированное или переменное скользящее окно по значениям.
Взвешенное окно: Взвешенное, не прямоугольное окно, предоставленное
scipy.signalбиблиотека.Расширяющееся окно: Накопительное окно по значениям.
Экспоненциально взвешенное окно: Накопительное и экспоненциально взвешенное окно по значениям.
Концепция |
Метод |
Возвращаемый объект |
Поддерживает окна на основе времени |
Поддерживает цепочечные группировки |
Поддерживает метод table |
Поддерживает онлайн-операции |
|---|---|---|---|---|---|---|
Скользящее окно |
|
|
Да |
Да |
Да (начиная с версии 1.3) |
Нет |
Взвешенное окно |
|
|
Нет |
Нет |
Нет |
Нет |
Расширяющееся окно |
|
|
Нет |
Да |
Да (начиная с версии 1.3) |
Нет |
Экспоненциально взвешенное окно |
|
|
Нет |
Да (начиная с версии 1.2) |
Нет |
Да (начиная с версии 1.3) |
Как отмечено выше, некоторые операции поддерживают указание окна на основе временного смещения:
In [4]: s = pd.Series(range(5), index=pd.date_range('2020-01-01', periods=5, freq='1D'))
In [5]: s.rolling(window='2D').sum()
Out[5]:
2020-01-01 0.0
2020-01-02 1.0
2020-01-03 3.0
2020-01-04 5.0
2020-01-05 7.0
Freq: D, dtype: float64
Кроме того, некоторые методы поддерживают цепочку groupby операция с оконной операцией, которая сначала группирует данные по указанным ключам, а затем выполняет оконную операцию для каждой группы.
In [6]: df = pd.DataFrame({'A': ['a', 'b', 'a', 'b', 'a'], 'B': range(5)})
In [7]: df.groupby('A').expanding().sum()
Out[7]:
B
A
a 0 0.0
2 2.0
4 6.0
b 1 1.0
3 4.0
Примечание
Операции с окнами в настоящее время поддерживают только числовые данные (целые и вещественные числа) и всегда возвращают float64 значения.
Предупреждение
Некоторые оконные агрегации, mean, sum, var и std методы могут страдать от числовой
неточности из-за того, что базовые алгоритмы оконного суммирования накапливают суммы. Когда значения различаются
по величине \(1/np.finfo(np.double).eps\) это приводит к усечению. Следует отметить, что большие значения могут повлиять на окна, которые не включают эти значения. суммирование по методу Кахана используется для вычисления скользящих сумм для максимального сохранения точности.
Добавлено в версии 1.3.0.
Некоторые оконные операции также поддерживают method='table' опция в конструкторе, которая
выполняет операцию оконного преобразования по всему DataFrame вместо одного столбца или строки за раз.
Это может дать полезный прирост производительности для DataFrame со многими столбцами или строками
(с соответствующим axis аргумент) или возможность использовать другие столбцы во время операции оконного преобразования. The method='table' опция может использоваться только если engine='numba' указан
в соответствующем вызове метода.
Например, взвешенное среднее расчет может
быть вычислен с apply() путем указания отдельного столбца весов.
In [8]: def weighted_mean(x):
...: arr = np.ones((1, x.shape[1]))
...: arr[:, :2] = (x[:, :2] * x[:, 2]).sum(axis=0) / x[:, 2].sum()
...: return arr
...:
In [9]: df = pd.DataFrame([[1, 2, 0.6], [2, 3, 0.4], [3, 4, 0.2], [4, 5, 0.7]])
In [10]: df.rolling(2, method="table", min_periods=0).apply(weighted_mean, raw=True, engine="numba") # noqa: E501
Out[10]:
0 1 2
0 1.000000 2.000000 1.0
1 1.800000 2.000000 1.0
2 3.333333 2.333333 1.0
3 1.555556 7.000000 1.0
Добавлено в версии 1.3.
Некоторые оконные операции также поддерживают online метод после создания объекта скользящего окна
который возвращает новый объект, поддерживающий передачу новых DataFrame или Series объекты
для продолжения оконных вычислений с новыми значениями (т.е. онлайн-вычисления).
Методы на этом новом объекте окон должны сначала вызвать метод агрегации, чтобы "подготовить" начальное
состояние онлайн-вычисления. Затем новые DataFrame или Series объекты могут быть переданы в update аргумент для продолжения расчета оконной функции.
In [11]: df = pd.DataFrame([[1, 2, 0.6], [2, 3, 0.4], [3, 4, 0.2], [4, 5, 0.7]])
In [12]: df.ewm(0.5).mean()
Out[12]:
0 1 2
0 1.000000 2.000000 0.600000
1 1.750000 2.750000 0.450000
2 2.615385 3.615385 0.276923
3 3.550000 4.550000 0.562500
In [13]: online_ewm = df.head(2).ewm(0.5).online()
In [14]: online_ewm.mean()
Out[14]:
0 1 2
0 1.00 2.00 0.60
1 1.75 2.75 0.45
In [15]: online_ewm.mean(update=df.tail(1))
Out[15]:
0 1 2
3 3.307692 4.307692 0.623077
Все операции оконного преобразования поддерживают min_periods аргумент, который определяет минимальное количество не-np.nan значений, которые должно иметь окно; в противном случае результирующее значение равно np.nan.
min_periods по умолчанию равно 1 для временных окон и window для фиксированных окон
In [16]: s = pd.Series([np.nan, 1, 2, np.nan, np.nan, 3])
In [17]: s.rolling(window=3, min_periods=1).sum()
Out[17]:
0 NaN
1 1.0
2 3.0
3 3.0
4 2.0
5 3.0
dtype: float64
In [18]: s.rolling(window=3, min_periods=2).sum()
Out[18]:
0 NaN
1 NaN
2 3.0
3 3.0
4 NaN
5 NaN
dtype: float64
# Equivalent to min_periods=3
In [19]: s.rolling(window=3, min_periods=None).sum()
Out[19]:
0 NaN
1 NaN
2 NaN
3 NaN
4 NaN
5 NaN
dtype: float64
Кроме того, все операции скользящего окна поддерживают aggregate метод для возврата результата нескольких агрегаций, примененных к окну.
In [20]: df = pd.DataFrame({"A": range(5), "B": range(10, 15)})
In [21]: df.expanding().agg(["sum", "mean", "std"])
Out[21]:
A B
sum mean std sum mean std
0 0.0 0.0 NaN 10.0 10.0 NaN
1 1.0 0.5 0.707107 21.0 10.5 0.707107
2 3.0 1.0 1.000000 33.0 11.0 1.000000
3 6.0 1.5 1.290994 46.0 11.5 1.290994
4 10.0 2.0 1.581139 60.0 12.0 1.581139
Скользящее окно#
Общая поддержка скользящих окон позволяет указывать окна как фиксированное количество наблюдений или переменное количество наблюдений на основе смещения. Если предоставлено смещение на основе времени, соответствующий индекс на основе времени должен быть монотонным.
In [22]: times = ['2020-01-01', '2020-01-03', '2020-01-04', '2020-01-05', '2020-01-29']
In [23]: s = pd.Series(range(5), index=pd.DatetimeIndex(times))
In [24]: s
Out[24]:
2020-01-01 0
2020-01-03 1
2020-01-04 2
2020-01-05 3
2020-01-29 4
dtype: int64
# Window with 2 observations
In [25]: s.rolling(window=2).sum()
Out[25]:
2020-01-01 NaN
2020-01-03 1.0
2020-01-04 3.0
2020-01-05 5.0
2020-01-29 7.0
dtype: float64
# Window with 2 days worth of observations
In [26]: s.rolling(window='2D').sum()
Out[26]:
2020-01-01 0.0
2020-01-03 1.0
2020-01-04 3.0
2020-01-05 5.0
2020-01-29 4.0
dtype: float64
Для всех поддерживаемых функций агрегации см. Функции скользящего окна.
Центрирование окон#
По умолчанию метки устанавливаются на правый край окна, но
center доступен ключевой параметр, позволяющий установить метки по центру.
In [27]: s = pd.Series(range(10))
In [28]: s.rolling(window=5).mean()
Out[28]:
0 NaN
1 NaN
2 NaN
3 NaN
4 2.0
5 3.0
6 4.0
7 5.0
8 6.0
9 7.0
dtype: float64
In [29]: s.rolling(window=5, center=True).mean()
Out[29]:
0 NaN
1 NaN
2 2.0
3 3.0
4 4.0
5 5.0
6 6.0
7 7.0
8 NaN
9 NaN
dtype: float64
Это также может быть применено к индексам типа datetime.
Добавлено в версии 1.3.0.
In [30]: df = pd.DataFrame(
....: {"A": [0, 1, 2, 3, 4]}, index=pd.date_range("2020", periods=5, freq="1D")
....: )
....:
In [31]: df
Out[31]:
A
2020-01-01 0
2020-01-02 1
2020-01-03 2
2020-01-04 3
2020-01-05 4
In [32]: df.rolling("2D", center=False).mean()
Out[32]:
A
2020-01-01 0.0
2020-01-02 0.5
2020-01-03 1.5
2020-01-04 2.5
2020-01-05 3.5
In [33]: df.rolling("2D", center=True).mean()
Out[33]:
A
2020-01-01 0.5
2020-01-02 1.5
2020-01-03 2.5
2020-01-04 3.5
2020-01-05 4.0
Конечные точки скользящего окна#
Включение конечных точек интервала в расчёты скользящего окна может быть указано с помощью closed
параметр:
Значение |
Поведение |
|---|---|
|
закрытая правая конечная точка |
|
закрытая левая граница |
|
закрыть оба конца |
|
открытые конечные точки |
Например, открытая правая конечная точка полезна во многих задачах, требующих отсутствия загрязнения от текущей информации к прошлой информации. Это позволяет скользящему окну вычислять статистики «до этого момента времени», но не включая этот момент времени.
In [34]: df = pd.DataFrame(
....: {"x": 1},
....: index=[
....: pd.Timestamp("20130101 09:00:01"),
....: pd.Timestamp("20130101 09:00:02"),
....: pd.Timestamp("20130101 09:00:03"),
....: pd.Timestamp("20130101 09:00:04"),
....: pd.Timestamp("20130101 09:00:06"),
....: ],
....: )
....:
In [35]: df["right"] = df.rolling("2s", closed="right").x.sum() # default
In [36]: df["both"] = df.rolling("2s", closed="both").x.sum()
In [37]: df["left"] = df.rolling("2s", closed="left").x.sum()
In [38]: df["neither"] = df.rolling("2s", closed="neither").x.sum()
In [39]: df
Out[39]:
x right both left neither
2013-01-01 09:00:01 1 1.0 1.0 NaN NaN
2013-01-01 09:00:02 1 2.0 2.0 1.0 1.0
2013-01-01 09:00:03 1 2.0 3.0 2.0 1.0
2013-01-01 09:00:04 1 2.0 3.0 2.0 1.0
2013-01-01 09:00:06 1 1.0 2.0 1.0 NaN
Пользовательское скользящее окно#
В дополнение к принятию целого числа или смещения в качестве window аргумент, rolling также принимает BaseIndexer подкласс, который позволяет пользователю определить пользовательский метод для вычисления границ окна. BaseIndexer подкласс должен определить get_window_bounds метод, возвращающий кортеж из двух массивов: первый — начальные индексы окон, второй — конечные индексы окон. Кроме того, num_values, min_periods, center, closed
и step будет автоматически передан в get_window_bounds и определенный метод всегда должен принимать эти аргументы.
Например, если у нас есть следующее DataFrame
In [40]: use_expanding = [True, False, True, False, True]
In [41]: use_expanding
Out[41]: [True, False, True, False, True]
In [42]: df = pd.DataFrame({"values": range(5)})
In [43]: df
Out[43]:
values
0 0
1 1
2 2
3 3
4 4
и мы хотим использовать расширяющееся окно, где use_expanding является True иначе окно размером
1, мы можем создать следующее BaseIndexer подкласс:
In [44]: from pandas.api.indexers import BaseIndexer
In [45]: class CustomIndexer(BaseIndexer):
....: def get_window_bounds(self, num_values, min_periods, center, closed, step):
....: start = np.empty(num_values, dtype=np.int64)
....: end = np.empty(num_values, dtype=np.int64)
....: for i in range(num_values):
....: if self.use_expanding[i]:
....: start[i] = 0
....: end[i] = i + 1
....: else:
....: start[i] = i
....: end[i] = i + self.window_size
....: return start, end
....:
In [46]: indexer = CustomIndexer(window_size=1, use_expanding=use_expanding)
In [47]: df.rolling(indexer).sum()
Out[47]:
values
0 0.0
1 1.0
2 3.0
3 3.0
4 10.0
Вы можете посмотреть другие примеры BaseIndexer подклассы здесь
Один подкласс, заслуживающий внимания среди этих примеров, это VariableOffsetWindowIndexer который позволяет выполнять скользящие операции с нефиксированным смещением, таким как BusinessDay.
In [48]: from pandas.api.indexers import VariableOffsetWindowIndexer
In [49]: df = pd.DataFrame(range(10), index=pd.date_range("2020", periods=10))
In [50]: offset = pd.offsets.BDay(1)
In [51]: indexer = VariableOffsetWindowIndexer(index=df.index, offset=offset)
In [52]: df
Out[52]:
0
2020-01-01 0
2020-01-02 1
2020-01-03 2
2020-01-04 3
2020-01-05 4
2020-01-06 5
2020-01-07 6
2020-01-08 7
2020-01-09 8
2020-01-10 9
In [53]: df.rolling(indexer).sum()
Out[53]:
0
2020-01-01 0.0
2020-01-02 1.0
2020-01-03 2.0
2020-01-04 3.0
2020-01-05 7.0
2020-01-06 12.0
2020-01-07 6.0
2020-01-08 7.0
2020-01-09 8.0
2020-01-10 9.0
Для некоторых задач доступна информация о будущем для анализа. Например, это происходит, когда каждая точка данных представляет собой полный временной ряд, считанный из эксперимента, и задача состоит в извлечении базовых условий. В таких случаях может быть полезно выполнять опережающие вычисления скользящего окна.
FixedForwardWindowIndexer класс доступен для этой цели.
Это BaseIndexer подкласс реализует закрытое окно скольжения фиксированной ширины с опережением, и мы можем использовать его следующим образом:
In [54]: from pandas.api.indexers import FixedForwardWindowIndexer
In [55]: indexer = FixedForwardWindowIndexer(window_size=2)
In [56]: df.rolling(indexer, min_periods=1).sum()
Out[56]:
0
2020-01-01 1.0
2020-01-02 3.0
2020-01-03 5.0
2020-01-04 7.0
2020-01-05 9.0
2020-01-06 11.0
2020-01-07 13.0
2020-01-08 15.0
2020-01-09 17.0
2020-01-10 9.0
Мы также можем достичь этого, используя срезы, применяя скользящую агрегацию, а затем переворачивая результат, как показано в примере ниже:
In [57]: df = pd.DataFrame(
....: data=[
....: [pd.Timestamp("2018-01-01 00:00:00"), 100],
....: [pd.Timestamp("2018-01-01 00:00:01"), 101],
....: [pd.Timestamp("2018-01-01 00:00:03"), 103],
....: [pd.Timestamp("2018-01-01 00:00:04"), 111],
....: ],
....: columns=["time", "value"],
....: ).set_index("time")
....:
In [58]: df
Out[58]:
value
time
2018-01-01 00:00:00 100
2018-01-01 00:00:01 101
2018-01-01 00:00:03 103
2018-01-01 00:00:04 111
In [59]: reversed_df = df[::-1].rolling("2s").sum()[::-1]
In [60]: reversed_df
Out[60]:
value
time
2018-01-01 00:00:00 201.0
2018-01-01 00:00:01 101.0
2018-01-01 00:00:03 214.0
2018-01-01 00:00:04 111.0
Скользящее применение#
The apply() функция принимает дополнительный func аргумент и выполняет общие скользящие вычисления. Параметр func аргумент должен быть единственной функцией,
которая возвращает единственное значение из входного ndarray. raw указывает, приводятся ли окна как Series объекты (raw=False) или объектов ndarray (raw=True).
In [61]: def mad(x):
....: return np.fabs(x - x.mean()).mean()
....:
In [62]: s = pd.Series(range(10))
In [63]: s.rolling(window=4).apply(mad, raw=True)
Out[63]:
0 NaN
1 NaN
2 NaN
3 1.0
4 1.0
5 1.0
6 1.0
7 1.0
8 1.0
9 1.0
dtype: float64
Движок Numba#
Дополнительно, apply() может использовать Numba
если установлен как опциональная зависимость. Агрегация apply может быть выполнена с использованием Numba, указав
engine='numba' и engine_kwargs аргументы (raw также должно быть установлено в True). См. улучшение производительности с помощью Numba для общего использования аргументов и соображений производительности.
Numba будет применяться в двух потенциальных процедурах:
Если
funcявляется стандартной функцией Python, движок будет JIT переданная функция.funcтакже может быть JIT-функцией, в этом случае движок не будет повторно JIT-компилировать функцию.Движок JIT-компилирует цикл for, где функция apply применяется к каждому окну.
The engine_kwargs аргумент представляет собой словарь ключевых аргументов, которые будут переданы в
декоратор numba.jit.
Эти ключевые аргументы будут применены к оба переданная функция (если это стандартная функция Python)
и цикл apply для каждого окна.
Добавлено в версии 1.3.0.
mean, median, max, min, и sum также поддерживает engine и engine_kwargs аргументы.
Бинарные оконные функции#
cov() и corr() может вычислять статистику скользящего окна для двух Series или любая комбинация DataFrame/Series или
DataFrame/DataFrame. Вот поведение в каждом случае:
два
Series: вычислить статистику для пары.DataFrame/Series: вычисляет статистику для каждого столбца DataFrame с переданным Series, возвращая DataFrame.DataFrame/DataFrame: по умолчанию вычисляет статистику для совпадающих имён столбцов, возвращая DataFrame. Если аргумент ключевого словаpairwise=Trueпередаётся, затем вычисляет статистику для каждой пары столбцов, возвращаяDataFrameсMultiIndexзначениями которого являются рассматриваемые даты (см. следующий раздел).
Например:
In [64]: df = pd.DataFrame(
....: np.random.randn(10, 4),
....: index=pd.date_range("2020-01-01", periods=10),
....: columns=["A", "B", "C", "D"],
....: )
....:
In [65]: df = df.cumsum()
In [66]: df2 = df[:4]
In [67]: df2.rolling(window=2).corr(df2["B"])
Out[67]:
A B C D
2020-01-01 NaN NaN NaN NaN
2020-01-02 -1.0 1.0 -1.0 1.0
2020-01-03 1.0 1.0 1.0 -1.0
2020-01-04 -1.0 1.0 1.0 -1.0
Вычисление скользящих попарных ковариаций и корреляций#
В анализе финансовых данных и других областях часто вычисляют ковариационные
и корреляционные матрицы для набора временных рядов. Часто также интересуются
скользящими ковариационными и корреляционными матрицами. Это можно
сделать, передав pairwise аргумент ключевого слова, который в случае
DataFrame входные данные дадут MultiIndexed DataFrame чей index являются датами в вопросе. В случае одного аргумента DataFrame pairwise аргумент
можно даже опустить:
Примечание
Пропущенные значения игнорируются, и каждая запись вычисляется с использованием попарно полных наблюдений.
Предполагая, что пропущенные данные отсутствуют случайным образом, это дает оценку ковариационной матрицы, которая является несмещенной. Однако для многих приложений эта оценка может быть неприемлемой, потому что оцененная ковариационная матрица не гарантированно является положительно полуопределенной. Это может привести к оцененным корреляциям с абсолютными значениями больше единицы, и/или необратимой ковариационной матрице. См. Оценка ковариационных матриц для получения дополнительной информации.
In [68]: covs = (
....: df[["B", "C", "D"]]
....: .rolling(window=4)
....: .cov(df[["A", "B", "C"]], pairwise=True)
....: )
....:
In [69]: covs
Out[69]:
B C D
2020-01-01 A NaN NaN NaN
B NaN NaN NaN
C NaN NaN NaN
2020-01-02 A NaN NaN NaN
B NaN NaN NaN
... ... ... ...
2020-01-09 B 0.342006 0.230190 0.052849
C 0.230190 1.575251 0.082901
2020-01-10 A -0.333945 0.006871 -0.655514
B 0.649711 0.430860 0.469271
C 0.430860 0.829721 0.055300
[30 rows x 3 columns]
Взвешенное окно#
The win_type аргумент в .rolling генерирует взвешенные окна, которые обычно используются в фильтрации и спектральной оценке. win_type должна быть строкой, соответствующей оконная функция scipy.signal.
Scipy должен быть установлен для использования этих окон, и дополнительные аргументы,
которые принимают методы окон Scipy, должны быть указаны в функции агрегации.
In [70]: s = pd.Series(range(10))
In [71]: s.rolling(window=5).mean()
Out[71]:
0 NaN
1 NaN
2 NaN
3 NaN
4 2.0
5 3.0
6 4.0
7 5.0
8 6.0
9 7.0
dtype: float64
In [72]: s.rolling(window=5, win_type="triang").mean()
Out[72]:
0 NaN
1 NaN
2 NaN
3 NaN
4 2.0
5 3.0
6 4.0
7 5.0
8 6.0
9 7.0
dtype: float64
# Supplementary Scipy arguments passed in the aggregation function
In [73]: s.rolling(window=5, win_type="gaussian").mean(std=0.1)
Out[73]:
0 NaN
1 NaN
2 NaN
3 NaN
4 2.0
5 3.0
6 4.0
7 5.0
8 6.0
9 7.0
dtype: float64
Для всех поддерживаемых функций агрегации см. Взвешенные оконные функции.
Расширяющееся окно#
Расширяющееся окно даёт значение статистики агрегации со всеми доступными данными до этого момента времени. Поскольку эти вычисления являются частным случаем скользящей статистики, они реализованы в pandas так, что следующие два вызова эквивалентны:
In [74]: df = pd.DataFrame(range(5))
In [75]: df.rolling(window=len(df), min_periods=1).mean()
Out[75]:
0
0 0.0
1 0.5
2 1.0
3 1.5
4 2.0
In [76]: df.expanding(min_periods=1).mean()
Out[76]:
0
0 0.0
1 0.5
2 1.0
3 1.5
4 2.0
Для всех поддерживаемых функций агрегации см. Расширяющиеся оконные функции.
Экспоненциально взвешенное окно#
Экспоненциально взвешенное окно похоже на расширяющееся окно, но с экспоненциальным уменьшением веса каждой предыдущей точки относительно текущей.
В общем случае взвешенное скользящее среднее рассчитывается как
где \(x_t\) это вход, \(y_t\) является результатом и \(w_i\) являются весами.
Для всех поддерживаемых функций агрегации см. Экспоненциально взвешенные оконные функции.
Функции EW поддерживают два варианта экспоненциальных весов.
По умолчанию, adjust=True, использует веса \(w_i = (1 - \alpha)^i\)
что даёт
Когда adjust=False указан, скользящие средние рассчитываются как
что эквивалентно использованию весов
Примечание
Эти уравнения иногда записываются в терминах \(\alpha' = 1 - \alpha\), например,
Разница между двумя вышеуказанными вариантами возникает потому, что мы
имеем дело с рядами, имеющими конечную историю. Рассмотрим ряд бесконечной
истории, с adjust=True:
Отметим, что знаменатель представляет собой геометрическую прогрессию с начальным членом, равным 1, и знаменателем \(1 - \alpha\) у нас есть
что является тем же выражением, что и adjust=False выше и поэтому
показывает эквивалентность двух вариантов для бесконечных рядов.
Когда adjust=False, у нас есть \(y_0 = x_0\) и
\(y_t = \alpha x_t + (1 - \alpha) y_{t-1}\).
Поэтому предполагается, что \(x_0\) не является обычным значением, а представляет собой экспоненциально взвешенный момент бесконечного ряда до этой точки.
Должен иметь \(0 < \alpha \leq 1\), и хотя возможно передать \(\alpha\) непосредственно, часто проще думать либо о span, центр масс (com) или период полураспада момента EW:
Необходимо указать ровно один из span, центр масс, период полураспада и alpha для функций EW:
Span соответствует тому, что обычно называют «скользящим средним N-дневного экспоненциального взвешивания».
Центр масс имеет более физическую интерпретацию и может рассматриваться в терминах диапазона: \(c = (s - 1) / 2\).
Период полураспада — это период времени, за который экспоненциальный вес уменьшается до половины.
Альфа указывает коэффициент сглаживания напрямую.
Вы также можете указать halflife в терминах конвертируемой в timedelta единицы для указания количества
времени, необходимого для того, чтобы наблюдение уменьшилось до половины своего значения, при также указании последовательности times.
In [77]: df = pd.DataFrame({"B": [0, 1, 2, np.nan, 4]})
In [78]: df
Out[78]:
B
0 0.0
1 1.0
2 2.0
3 NaN
4 4.0
In [79]: times = ["2020-01-01", "2020-01-03", "2020-01-10", "2020-01-15", "2020-01-17"]
In [80]: df.ewm(halflife="4 days", times=pd.DatetimeIndex(times)).mean()
Out[80]:
B
0 0.000000
1 0.585786
2 1.523889
3 1.523889
4 3.233686
Следующая формула используется для вычисления экспоненциально взвешенного среднего с входным вектором времен:
ExponentialMovingWindow также имеет ignore_na аргумент, который определяет, как
промежуточные нулевые значения влияют на расчёт весов.
Когда ignore_na=False (по умолчанию), веса рассчитываются на основе абсолютных позиций, так что промежуточные нулевые значения влияют на результат.
Когда ignore_na=True,
веса рассчитываются, игнорируя промежуточные нулевые значения.
Например, предполагая adjust=True, если ignore_na=False, взвешенное среднее 3, NaN, 5 будет вычисляться как
В то время как если ignore_na=True, взвешенное среднее будет рассчитано как
The var(), std(), и cov() функции имеют bias аргумент,
указывающий, должен ли результат содержать смещённую или несмещённую статистику.
Например, если bias=True, ewmvar(x) рассчитывается как
ewmvar(x) = ewma(x**2) - ewma(x)**2;
тогда как если bias=False (по умолчанию), смещённые статистики дисперсии масштабируются коэффициентами устранения смещения
(Для \(w_i = 1\), это сводится к обычному \(N / (N - 1)\) фактор, с \(N = t + 1\).) См. Взвешенная выборочная дисперсия на Википедии для дополнительных деталей.