3

我有一些有效的代码,但有点瓶颈,我一直在试图弄清楚如何加速它。它在一个循环中,我不知道如何对其进行矢量化。

我有一个代表时间序列数据的二维数组 vals。行是日期,列是不同的系列。我试图按月存储数据以对其执行各种操作(求和、平均值等)。这是我当前的代码:

allDts; %Dates/times for vals.  Size is [size(vals, 1), 1]
vals;
[Y M] = datevec(allDts);
fomDates = unique(datenum(Y, M, 1)); %first of the month dates

[Y M] = datevec(fomDates);
nextFomDates = datenum(Y, M, DateUtil.monthLength(Y, M)+1);

newVals = nan(length(fomDates), size(vals, 2)); %preallocate for speed

for k = 1:length(fomDates);

下一行是瓶颈,因为我多次调用它。(循环)

    idx = (allDts >= fomDates(k)) & (allDts < nextFomDates(k));
    bucketed = vals(idx, :);
    newVals(k, :) = nansum(bucketed);
end %for

有任何想法吗?提前致谢。

4

2 回答 2

2

这是一个很难矢量化的问题。我可以建议一种使用CELLFUN的方法,但我不能保证它会更快地解决您的问题(您必须自己根据您正在使用的特定数据集进行计时)。正如在另一个 SO question中所讨论的,矢量化并不总是比 for 循环更快。它可以是非常具体的问题,这是最好的选择。有了这个免责声明,我将建议您尝试两种解决方案:CELLFUN 版本和可能运行得更快的 for 循环版本的修改。

细胞乐解决方案:

[Y,M] = datevec(allDts);
monthStart = datenum(Y,M,1);  % Start date of each month
[monthStart,sortIndex] = sort(monthStart);  % Sort the start dates
[uniqueStarts,uniqueIndex] = unique(monthStart);  % Get unique start dates

valCell = mat2cell(vals(sortIndex,:),diff([0 uniqueIndex]));
newVals = cellfun(@nansum,valCell,'UniformOutput',false);

对MAT2CELL的调用将具有相同开始日期的 val行分组到单元数组 valCell 的单元。变量newVals将是一个长度为numel(uniqueStarts)的单元格数组,其中每个单元格将包含对valCell的相应单元格执行nansum的结果

FOR循环解决方案:

[Y,M] = datevec(allDts);
monthStart = datenum(Y,M,1);  % Start date of each month
[monthStart,sortIndex] = sort(monthStart);  % Sort the start dates
[uniqueStarts,uniqueIndex] = unique(monthStart);  % Get unique start dates

vals = vals(sortIndex,:);  % Sort the values according to start date
nMonths = numel(uniqueStarts);
uniqueIndex = [0 uniqueIndex];
newVals = nan(nMonths,size(vals,2));  % Preallocate
for iMonth = 1:nMonths,
  index = (uniqueIndex(iMonth)+1):uniqueIndex(iMonth+1);
  newVals(iMonth,:) = nansum(vals(index,:));
end
于 2009-05-14T14:47:56.970 回答
0

如果您需要做的只是形成矩阵行的总和或平均值,其中行根据另一个变量(日期)求和,然后使用我的合并函数。它旨在完全执行此操作,根据指标系列的值减少数据。(实际上,consolidator 也可以处理 nd 数据,并且有容差,但您需要做的就是将月份和年份信息传递给它。)

在 Matlab Central 上的文件交换中查找合并器

于 2009-05-14T21:12:24.037 回答