【发布时间】:2016-12-12 08:56:11
【问题描述】:
我有三个矩阵:
Values = [200x7] doubles
numOfStrings = [82 78 75 73 72 71 70] %(for example)
numOfColumns = [1 4]
numOfColumns 可以包含从 1 到 7 的任意一组不同的值。例如 [1 2 3] 或 [4 7] 或 [1 5 6 7]。显然,最大的numOfColumns 可以是[1 2 3 4 5 6 7]。
numOfColumns 显示我想要获取的列。 numOfStrings 显示了我需要的那些列的行。 IE。在我的示例中,我想获取列 1 和 4。因此,我想从1 列获取82 第一行,从4th 获取73 第一行。
即如果numOfColumns = [1 4] 那么
myCell{1} = Values( 1:82,1); % Values(numOfStrings(numOfColumn(1)), numOfColumn(1))
myCell{2} = Values( 1:73,4); % Values(numOfStrings(numOfColumn(2)), numOfColumn(2))
附:没有必要将其保存到单元格数组中。如果您能提供任何其他解决方案,我将不胜感激。
我正在寻找最快的方法来做到这一点,这可能是避免for 循环并使用矢量化。
我对@987654342@ 函数想了很多。但我不知道如何返回不同大小的数组!因为myCell{1} - [82x1] 和myCell{2} - [73x1]。我想我不能使用bsxfun 或arrayfun。
结果:
-
使用
for循环类似@Will 's answer:for jj = 1:numel(numOfColumns) myCell{rowNumber(numOfColumns(jj)),numOfColumns(jj)} = Values( 1:numOfStrings(numOfColumns(jj)),numOfColumns(jj)); end经过的时间是 157 秒
-
使用
arrayfun类似@Yishai E 's answer:myCell(sub2ind(size(myCell),rowNumber(numOfColumns),numOfColumns)) = arrayfun( @(nOC) Values( 1:numOfStrings(nOC),nOC), numOfColumns, 'UniformOutput', false);经过的时间是 179 秒
-
使用
bsxfun类似@rahnema1 's answer:idx = bsxfun(@ge,numOfStrings , (1:200).'); extracted_values = Values (idx); tempCell = mat2cell(extracted_values,numOfStrings); myCell(sub2ind(size(myCell),rowNumber(numOfColumns),numOfColumns)) = myCell(numOfColumns)';经过的时间是 204 秒
所以,我得到了很多可行的答案,其中一些按照我的要求进行了矢量化,但 for 循环仍然最快!
【问题讨论】:
-
您无法避免
for使用元胞数组循环。但是,最新版本的 MATLAB 对 JIT 进行了改进得多,因此与更标准的矢量化方法相比,循环更具竞争力。 -
我认为基准不正确
-
@rayryeng 三个答案中有两个没有使用
for。但我认为for-solution 更快,因为我无法正确实现矢量化代码... -
@rahnema1Yep,恐怕我无法有效地实现您的代码 - 我使用了很多辅助功能......但仍然无法弄清楚如何避免它们
-
我无法弄清楚时间是如何花费 179 s 的。你能提供一个带有实际尺寸的完整例子吗?
rowNumber是什么?试试这个:numcols_logical = false(1,numel(numOfColumns)); numcols_logical(numOfColumns) = true; extracted_values = Values(bsxfun(@ge, numOfStrings .* numcols_logical , (1:200).')); result= mat2cell(extracted_values,numOfStrings(numcols_logical));
标签: arrays matlab loops vectorization cell-array