我有三个矩阵:
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
显示了我需要的列的行。即在我的示例中,我希望获得列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))
P.S。没有必要将它保存到单元阵列中。如果您能提供任何其他解决方案我将不胜感激。
我正在寻找最快的方法,这可能是通过避免for
循环和使用矢量化来实现的。
我对sub2ind
功能有很多了解。但我无法弄清楚如何返回不同大小的数组!因为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
循环仍然最快!
答案 0 :(得分:2)
这可以解决您的问题,使用arrayfun,它“索引”索引函数的应用程序。不是真的,但它没有为numOfColumns中的每个条目调用解释器。有趣的是,这比其他答案中的非矢量化代码要慢! (对于1e5条目,0.95秒对0.23秒......)
arrayfun(@(nOC)Values(1:numOfStrings(nOC), nOC), numOfColumns, 'UniformOutput', false)
答案 1 :(得分:1)
% Get number of elements in NUMOFCOLUMNS
n = numel(numOfColumns);
% Set up output
myCell = cell(1,n);
% Loop through all NUMOFCOLUMNS values, storing to cell
for i = 1:n
myCell{i} = Values(1:numOfStrings(numOfColumns(i)), numOfColumns(i));
end
为您的示例提供输出
myCell =
[82x1 double] [73x1 double]
答案 2 :(得分:1)
您可以创建用于提取所需元素的逻辑索引:
idx = bsxfun(@ge,numOfStrings , (1:200).');
在MATLAB R2016b或Octave中(由于广播/扩展)可以写成:
idx = numOfStrings >= (1:200).';
提取值:
extracted_values = Values (idx);
然后使用mat2cell
将数据转换为单元格:
myCell = mat2cell(extracted_values,numOfStrings);
全部在一行:
myCell = mat2cell(Values (numOfStrings >= (1:200).'), numOfStrings);
如果您想使用不同大小的不同numOfColumns
来提取单元格的元素,您每次都可以这样做:
result = myCell(numOfColumns);
如果numOfStrings
和numOfColumns
都发生了变化,您需要在执行此操作后计算结果:
%convert numOfColumns to logical index:
numcols_logical = false(1,7);
numcols_logical(numOfColumns) = true;
extracted_values = Values ((numOfStrings .* numcols_logical) >= (1:200).');
如果你需要单元格数组
result= mat2cell(extracted_values,numOfStrings(numcols_logical));