我有时间序列数据,其中包含一些缺失的数据,我正在滚动窗口上运行一些估算功能。窗口长度不均匀,每个变量具有不同的开始和结束日期。我想删除任何缺少数据的窗口。窗户重叠,因此单个缺失的观察通常会从考虑中移除许多窗户。我想要的是从每个日期到包含它的窗口的映射。
目前,我有一个逻辑矩阵,每个可能的日期都有一行,然后每列代表一个窗口,该窗口具有该窗口日期的真值。然后我可以将该矩阵子集化为表示缺失数据的行,并且无论哪个列包含任何真值都是无效窗口。问题是逻辑矩阵变大(10k x 10k~100mb)并且可能有很多。我可以转换为稀疏,它解决了大小问题,但是当窗口很长时,要删除的窗口的计算变得非常慢。
这不是一个应该是资源密集型(内存或计算)的问题,是否有更好的方法?
编辑:让我添加一个例子,这样可能会更清楚一些。假设整套日期范围从1到100. Windows是1:10,2:11,3:12,依此类推到91:100(这些是统一的,但对于示例并不重要)。我有一个从5到25的系列,但是17的NaN。
那个NaN击出十个窗户(8:17到17:26)。我想从观察17到窗口8:17进行有效的映射。显然,当窗户长度均匀时,这很容易,但是当窗户不规则时,什么是有效的方法呢?
答案 0 :(得分:3)
逻辑比较花费的时间和资源很少。你确定这是一个瓶颈吗?
如果窗口创建非常耗时,您可能希望在while
循环中执行此操作,以便在窗口中遇到NaN
时可以跳过一些条目。
如果窗口创建速度很快,那肯定会有统一的长度,你可以简单地做
%# startEnd is created according to your example, but can be whatever quick method
startEnd = [(1:(100-windowSize+1))',(windowSize+1:100)'];
nanIdx = find(isnan(data))'; %'#
%# This line temporarily creates a logical array of size nWindows-by-numberOfNaNs
%# which is most likely smaller than nWindows-by-nWindows
badWindows = any(bsxfun(@le,startEnd(:,1),nanIdx) & bsxfun(@ge,startEnd(:,2),nanIdx),2);
startEnd(badWindows,:) = [];
答案 1 :(得分:1)
我编写了乔纳斯的解决方案,结果比我现有的慢了。但它确实消除了对大型阵列的需求,并让我以不同的方式思考问题。我只需要从窗户出发 - > (obs start,obs end)映射到obs - > (obs落入的各窗口的指标)接近。
所以我构建了一个包含每一天窗口索引的单元格数组(我可以使用NumObsx2矩阵,但我想允许可能复杂的窗口定义)。对于每个时间序列,我使用每个缺失数据点的索引来对映射进行子集化,以获得需要删除的所有窗口的索引。然后cell2mat将索引拉出单元格阵列,我可以删除坏窗口(谢天谢地,Matlab并不关心赋值中的重复索引)。
在我的时间里,这个方法大约是我原始方法的10倍,比Jonas的方法大15倍。地图中的索引可以存储为uint16,因此所需的内存远小于我的orignal解决方案(但仍然超过Jonas的方法)。
作为奖励,如果我想使用更复杂的标准,例如不超过5个NaN(参见所描述的不超过一个),我可以使用accumarray来计算指数。