让A
成为Matlab中的表格。是否有快速方式访问此表的子集?说出某列包含某个范围或类似范围内的数字的所有条目。问题是A
很大,我经常评估A(A.col1 == i,:)
。
然后我使用下面的简化代码
B = zeros(1,N);
for i=1:N
temp = A(A.col1 == i,:); % this line is evaluated often and takes a lot of time since A is big table
B(i) = FancyFunction(temp);
end
那么,A(A.col1 == i,:)
或A(ismember(A.col1,x),:)
是否有快速替代方案?
答案 0 :(得分:1)
不,您做对了。
A(some_logical_index,:)
是对table
的行进行子集的常规方法,也是AFAIK最快的方法。 A.col1 == i
产生一个逻辑索引,并且由于您要分别对每个组应用一个函数,因此一次可以这样做是合理的。或者,如果您的组基于一组键,则ismember(A.col1, x)
(其中x
是可能为非标量的数组)是常规的方法,并且可能是最快的方法,并且还会生成逻辑索引。
Matlab还提供了groupsummary
函数,它是您正在执行的此循环的“向量化”版本:它按列值对表进行分组,并将提供的函数应用于各组以产生一个输出。这可能是表达您在这里所做的工作的一种更简洁的方式。 理论上,这可能会更快,因为Matlab可以使用其内部线程来加速它。但是实际上,在我的测试中,groupsummary
的执行速度仅与常规M代码组循环一样快。可能是您想做的事情,以防Matlab在将来加速这一步,但您现在不会看到任何胜利(从Matlab R2019b开始)。
如果表包含齐次的列-所有数字或所有字符串或同一类的所有对象-您可以通过将表转换为数字,单元格或字符串类型的纯矩阵来加快此过程。这样可以避免table
类的开销。
您可以通过“投影” A
中未在FancyFunction
计算中实际使用的任何列来获得较小的加速:将数组A
按列子集为FancyFunction
所需的列;这样一来,您就无需花费时间和内存来子集任何不需要的列。