gpt4 book ai didi

python - 具有不规则时间间隔的大型数据集的快速 EMA 计算

转载 作者:太空宇宙 更新时间:2023-11-04 01:55:18 24 4
gpt4 key购买 nike

我有超过 800,000 行的数据。我想采用其中一列的指数移动平均线 (EMA)。时间采样不均匀,我想在每次更新(行)时衰减 EMA。我的代码是这样的:

window = 5            
for i in range(1, len(series)):
dt = series['datetime'][i] - series['datetime'][i - 1]
decay = 1 - numpy.exp(-dt / window)
result[i] = (1 - decay) * result[i - 1] + decay * series['midpoint'].iloc[i]
return pandas.Series(result, index=series.index)

问题是,对于 800,000 行,这非常慢。无论如何使用 numpy 的一些其他功能来优化它?我无法对其进行矢量化,因为 results[i] 依赖于 results[i-1]

此处示例数据:

Timestamp             Midpoint
1559655000001096130 2769.125
1559655000001162260 2769.127
1559655000001171688 2769.154
1559655000001408734 2769.138
1559655000001424200 2769.123
1559655000001433128 2769.110
1559655000001541560 2769.125
1559655000001640406 2769.125
1559655000001658436 2769.127
1559655000001755924 2769.129
1559655000001793266 2769.125
1559655000001878688 2769.143
1559655000002061024 2769.125

最佳答案

像下面这样需要我 0.34 秒来运行一系列具有 90 万行的不规则间隔数据怎么样?我假设 5 的窗口意味着 5 天的跨度。

首先,让我们创建一些示例数据。

# Create sample data for a price stream of 2.6m price observations sampled 1 second apart.
seconds_per_day = 60 * 60 * 24 # 60 seconds / minute * 60 minutes / hour * 24 hours / day
starting_value = 100
annualized_vol = .3
sampling_percentage = .35 # 35%
start_date = '2018-12-01'
end_date = '2018-12-31'

np.random.seed(0)
idx = pd.date_range(start=start_date, end=end_date, freq='s') # One second intervals.
periodic_vol = annualized_vol * (1/ 252 / seconds_per_day) ** 0.5
daily_returns = np.random.randn(len(idx)) * periodic_vol
cumulative_indexed_return = (1 + daily_returns).cumprod() * starting_value
index_level = pd.Series(cumulative_indexed_return, index=idx)

# Sample 35% of the simulated prices to create a time series of 907k rows with irregular time intervals.
s = index_level.sample(frac=sampling_percentage).sort_index()

现在让我们创建一个生成器函数来存储指数加权时间序列的最新值。这可以运行c。通过安装 numba、导入它然后在函数定义 @jit(nopython=True) 上方添加单个装饰器行,速度提高了 4 倍。

from numba import jit  # Optional, see below.

@jit(nopython=True) # Optional, see below.
def ewma(vals, decay_vals):
result = vals[0]
yield result
for val, decay in zip(vals[1:], decay_vals[1:]):
result = result * (1 - decay) + val * decay
yield result

现在让我们在不规则间隔的序列 s 上运行这个生成器。对于这个有 90 万行的示例,运行以下代码需要 1.2 秒。我可以选择使用来自 numba 的即时编译器,将执行时间进一步缩短至 0.34 秒。 .你首先需要install那个包,例如conda 安装 numba。请注意,我使用列表综合来填充生成器中的 ewma 值,然后在首先将其转换为数据帧后将这些值分配回原始系列。

# Assumes time series data is now named `s`.
window = 5 # Span of 5 days?
dt = pd.Series(s.index).diff().dt.total_seconds().div(seconds_per_day) # Measured in days.
decay = (1 - (dt / -window).apply(np.exp))
g = ewma_generator(s.values, decay.values)
result = s.to_frame('midpoint').assign(
ewma=pd.Series([next(g) for _ in range(len(s))], index=s.index))

>>> result.tail()
midpoint ewma
2018-12-30 23:59:45 103.894471 105.546004
2018-12-30 23:59:49 103.914077 105.545929
2018-12-30 23:59:50 103.901910 105.545910
2018-12-30 23:59:53 103.913476 105.545853
2018-12-31 00:00:00 103.910422 105.545720

>>> result.shape
(907200, 2)

为确保数字符合我们的直觉,让我们可视化每小时采样的结果。这对我来说很好。

obs_per_day = 24  # 24 hourly observations per day.
step = int(seconds_per_day / obs_per_day)
>>> result.iloc[::step, :].plot()

enter image description here

关于python - 具有不规则时间间隔的大型数据集的快速 EMA 计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56956832/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com