我真的希望文档更清楚地说明在 Matlab 中将 accumarray 用于 ND 大小矩阵。无论如何,我在这里完全感到困惑并寻求一些建议。这是挑战:
我有一个 3D 数据矩阵。
- ROWS 是单独的河流
- 列是观察日期
- PAGES 是数据收集的时间间隔
对于此示例,我们假设每次观察都是 5 分钟间隔内流过仪表的水量。但是,我现在希望将数据重新采样到 N 分钟的间隔(显然是 5 的倍数)。让我们选择 NMINS = 15。
所以,我想做的是在 NMINS 分钟间隔内找到水量的总和或平均值。也就是说,ROWS 和 COLUMNS 不会改变,但 PAGES 的维度和值将被抽取/聚合。
我可以获得页面的分组值。也就是说,我需要分组的值。如果它是一天的一条河流,没问题。但是,我有数百天,数十条河流。
我已经做到了这一点:
创建测试时间向量
NMINS = 15; % Bucket by every 15 mins or 20, etc.
N5MINS = 5 * 12 * 24 * 2; % Keep small - Two days of 5 min datenums
dnums = datenum(2016,3,20,0,0:5:N5MINS,0);
% Trim dnums to start at random time for edge case and keep only mins
mins = rem(dnums(25:end-30),1)'; % Create column vector
为测试创建随机矩阵
rng(123); % Set seed for reproducibility
X = randi(100,12,9,length(mins)); % Test matrix
以分钟为单位查找时间
[~,~,~,H,M] = datevec( mins );
H = 60 .* (H - H(1));
现在查找与我们的存储桶对应的所有时间
idxMIN = mod( M+H, NMINS )==0;
idxNewP = idxMIN; % This is used to align the new river matrix
[R,C,P] = size(X); % We'll drop P and use newP
newP = sum(idxNewP); % Number of PAGES in final matrix (new)
% Final newX will have dimensions [R,C,newP]
重置分组索引
% Must shift one all as minute intervals represent data UP to that point
% for the actual grouping of data. Test if first bucket is a
% match and set accordingly
if idxMIN(1)
idxMIN = [1; idxMIN(1:end-1)];
subs = cumsum(idxMIN);
else
idxMIN = [0; idxMIN(1:end-1)];
subs = cumsum(idxMIN) + 1 ;
end
补充: 小组规模将不一致,我不能做出这样的假设(很遗憾)。在运行上述内容后考虑以下内容。
tsttbl = table();
tsttbl.dnumstr = datestr(mins(1:5));
tsttbl.Mins = M(1:5);
tsttbl.subs = subs(1:5);
tsttbl
输出显示第一组的大小为 1:
tsttbl =
dnumstr Mins subs
________ ____ ____
2:00 AM 0 1
2:05 AM 5 2
2:10 AM 10 2
2:15 AM 15 2
2:20 AM 20 3
最后,最终,我需要传递自定义函数。以上是一个快速说明问题的玩具示例。我很抱歉没有更清楚。
结束添加
这就是我绊倒的地方......
如何设置 subs 值以应用于每个页面以使用 accumarray?我完全被文档弄糊涂了。或者这实际上是错误的方法?值得我使用的是 Matlab 2015b。
老实说,任何帮助将不胜感激。
替代解决方案 这在回家的路上击中了我。Meshgrid是我的朋友...
一旦上面的单元格运行(注意我改变了矩阵 X 的大小),我们为整个矩阵创建索引,其中页面的“索引”(即时间)由“subs”中的值给出。为此,我使用网格网格。
[days,rivers,pages] = meshgrid(1:C,1:R,subs);
grpvals = [rivers(:) days(:) pages(:)];
tst = accumarray(grpvals,X(:),[R C newP],@sum);
可能不是内存效率最高的,因为我必须创建天数、河流和页面矩阵,然后最终创建一个新的 grpvals 数组。但是,它的优点是现在我可以使用 accumarray 并传递匿名函数、@std 等。
希望这对其他人有帮助!
非常感谢路易斯。