Реализация взвешенного среднего на лету в Python - PullRequest
0 голосов
/ 27 июня 2018

У меня есть поток поступающих данных, и я хочу реализовать скользящее среднее на лету. Если все элементы в скользящем среднем имеют одинаковый вес, это довольно легко реализовать с помощью «очереди», но я хочу, чтобы самые последние элементы имели более высокие веса, а распределение этих весов является линейным (не экспоненциальным).

Например, если скользящее среднее имеет длину 5, текущее значение должно иметь вес «1», предыдущее значение должно иметь вес «0,8» и т. Д. До пятого элемента в очереди, который должен иметь вес «0,2». «; поэтому весовой вектор: [0.2, 0.4, 0.6, 0.8, 1.0].

Мне было интересно, если кто-нибудь знает, как реализовать это Python. Если есть более быстрый способ сделать это, пожалуйста, порекомендуйте это мне; эффективность важна для моей конкретной работы.

1 Ответ

0 голосов
/ 03 июля 2018

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

average_(t) = x_(t) + aa*average_(t-1)

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

В любом случае, если память не является параметром эффективности, ваша проблема сводится к умножению вектора. Поэтому я бы предложил использовать библиотеку numpy . [1] [2] . Смотрите пример решения ниже (, возможно, вы найдете более эффективный ):

import numpy as np

stream = np.array((20, 40))
n = len(stream)

latest_scalar = 60
stream = np.append(stream, latest_scalar)

n += 1
# n represent the length of the stream
# I assumed that is more efficient to handle n without calling len() function
# may raise safety issue
weights = np.arange(1, n+1)
# [1, 2, 3]
average = np.dot(stream, weights).sum() / (n*(n+1)/2)
# (n*(n+1)/2): total of the weights
# output: 46.666... ok!
...