Vectorizing cumsum of table-vectors in a for loop
2 ビュー (過去 30 日間)
古いコメントを表示
Dear everyone, I have the following code which works perfectly fine and does what I want: the cumsum of the specified vectors of n vectors from a table in a cell-array vector. Now, I would like to understand if I can, anyhow, vectorialize this cumsum so to speed up the whole process.
The following is the code which works just fine, but I would like to speed up:
% n
n = size(cellarray,2);
% Cell Array Space Preallocation
tot{1,n} = [];
for k = 1:n
tot{k} = cellarray{1,k}{:,'tot'};
end
tot_s = sum([tot{:}],2);
I have tried this variant, but it seems to increase the total time, rather than decreasing it
% n
n = size(table,2);
for k = 1:n
tot_s = cumsum(cellarray{1,k}{:,'tot'},2);
end
I was wondering if it could exist a way to not use the loop at all and "vectorialize" this cumsum. I have tried the following code:
% n
n = size(table,2);
tot_s = cumsum(cellarray{1,1:n}{:,'tot'},2);
but I got the following error
% Expected one output from a curly brace or dot indexing expression, but there were 50 results (n = 50 in this particular case).
Any suggestion would be very helpful. For what concern the "data" in input, you can use whatever data you want, it does not matter. The structure is very simple: a table into a vector of cell-array with the name of the variable in each table be 'tot' and all the data in the vector are double.
0 件のコメント
採用された回答
Guillaume
2019 年 8 月 27 日
No, it's not possible to vectorise the loop unless you don't use tables. Even if you were using matrices in the cell array (which would require the table data to be homogeneous), I'm not sure you'd gain much over the loop.
Your first example uses sum instead of cumsum, if it's just the sum you're after, this is probably slightly faster:
tot = cellarray{1}.tot;
for idx = 2:numel(cellarray)
tot = tot + cellarray{idx}.tot;
end
If you're after cumsum, it may be more efficient to allocate the final matrix directly rather than going through a temporary cell array:
tot = zeros(height(cellarray{1}, numel(cellarray)));
for col = 1:numel(cellarray)
tot(:, col) = cellarray{col}.tot;
end
tot = cumsum(tot, 2);
Your second example doesn't make sense. You're cumsum'ing a single column at each step of the loop, that doesn't do much, and overwriting tot_s each step.
Also, I believe that dot indexing as I have used above is slightly faster than {} indexing for tables.
Finally, for preallocation:
tot = cell(size(cellarray));
would be clearer than the syntax you use.
その他の回答 (1 件)
Steven Lord
2019 年 8 月 27 日
You say you're using a cell array so I assume the arrays inside different cells are different sizes, shapes, or types. That would mean they cannot be concatenated together into an array. If they can be concatenated together into an array, do so and call cumsum on that array specifying the dimension over which you want to sum.
So what sizes, shapes, and/or types are the data arrays inside the cells in your cell array?
参考
カテゴリ
Help Center および File Exchange で Logical についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!