更新:我做了一些测试,发现Jonas的解决方案在处理不同大小的输入向量时是最快的。尤其是像angainor所指出的那样,该解决方案可以很好地扩展到大规模问题上——这是一个重要的测试,因为通常是大规模问题促使我们在SO上提出这些问题。感谢Jonas和tmpearce提供的解决方案——基于对大规模问题的效率考虑,我将答案选为Jonas。
我的问题:我有这个列向量:
Vec = [0; 1; 2; -1; -3; 0; 0; 2; 1; -1];
我希望将每个大于1的元素转换为一个长度等于该元素值的1序列。同样地,我想将每个小于-1的元素转换为一系列负数。因此,我的输出向量应该如下所示:
VecLong = [0; 1; 1; 1; -1; -1; -1; -1; 0; 0; 1; 1; 1; -1];
请注意,每个数字2都被改成了两个数字1,而数字-3被改成了三个数字-1。目前,我是这样解决这个问题的:
VecTemp = Vec;
VecTemp(VecTemp == 0) = 1;
VecLong = NaN(sum(abs(VecTemp)), 1);
c = 1;
for n = 1:length(Vec)
if abs(Vec(n)) <= 1
VecLong(c) = Vec(n);
c = c + 1;
else
VecLong(c:c + abs(Vec(n))) = sign(Vec(n));
c = c + abs(Vec(n));
end
end
这种方法并不太优雅,有没有人能提出更好的方法?注意:你可以假设 Vec
只包含整数值。感谢所有建议。
arrayfun
也很慢。循环通常比arrayfun
或cellfun
快得多,有时甚至与更好的矢量化解决方案相当竞争力,特别是如果预分配(就像你所做的那样)被正确地执行。它们只是因为声名狼藉而不受欢迎。不过一行代码也很有趣,特别是如果速度不是关键 :) - tmpearcearrayfun
和循环之间的差异,可以查看angainor在我的另一个SO问题这里提供的绝佳答案。顺便说一下,我已经给你的回答点赞了,但是由于速度问题,我恐怕无法授予答案标记。 - Colin T Bowers