如何对Eigen类向量的buyQuantity属性进行滚动窗口求和?
解决方案
针对Eigen::Vector
方案一:直接遍历切片元素求和
这是最直观的方式,和你之前用std::vector的逻辑一致,通过Eigen的索引或迭代器访问元素即可:
方式1:索引访问
for (size_t i = 30; i < trades.rows(); ++i) { double cum_buy_qty = 0; // 遍历窗口内的每个Trade元素 for (size_t k = i - 30; k <= i; ++k) { cum_buy_qty += trades(static_cast<Eigen::Index>(k)).buyQuantity; } // 这里处理求和结果 }
注意:Eigen的索引类型是Eigen::Index(通常为int或long),若循环变量是size_t,需做类型转换避免编译警告。
方式2:使用Eigen迭代器
利用Eigen容器的范围for支持,代码更简洁:
for (size_t i = 30; i < trades.rows(); ++i) { double cum_buy_qty = 0; auto slice = trades(Eigen::seq(static_cast<Eigen::Index>(i - 30), static_cast<Eigen::Index>(i))); for (const auto& trade : slice) { cum_buy_qty += trade.buyQuantity; } // 处理求和结果 }
方案二:前缀和优化(高效版)
如果向量规模较大,嵌套循环的O(n*window_size)复杂度会影响性能,推荐用前缀和将时间复杂度降到O(n):
- 先把所有Trade的
buyQuantity提取到Eigen数值向量中 - 计算前缀和数组
- 通过前缀和的差值快速得到窗口求和结果
// 1. 提取所有buyQuantity到数值向量 Eigen::VectorXd buy_qtys(trades.rows()); for (Eigen::Index j = 0; j < trades.rows(); ++j) { buy_qtys(j) = trades(j).buyQuantity; } // 2. 计算前缀和:prefix_sum[0] = 0,prefix_sum[k] = sum(buy_qtys[0..k-1]) Eigen::VectorXd prefix_sum(buy_qtys.rows() + 1); prefix_sum(0) = 0; prefix_sum.tail(buy_qtys.rows()) = buy_qtys.cumsum(); // 3. 滚动窗口求和(窗口包含i-30到i共31个元素) for (Eigen::Index i = 30; i < trades.rows(); ++i) { double cum_buy_qty = prefix_sum(i + 1) - prefix_sum(i - 30); // 处理求和结果 }
这种方法仅需一次遍历提取数值、一次遍历计算前缀和,之后每个窗口的求和都是O(1)操作,适合大数据量场景。
内容的提问来源于stack exchange,提问作者Nicolas REY
相关产品推荐
相关产品推荐

