如何在MATLAB中基于另一向量的重复值生成递增重置向量?
无需循环生成分组递增向量V2的简洁解法
嘿,这个需求我刚好折腾过,不用写for循环的话,有好几种高效又简洁的实现方式,给你分享几个实用的:
方法一:纯向量运算(最高效,无依赖)
这个方法完全靠MATLAB的内置向量函数搞定,不用任何循环或者额外工具箱:
V1 = [1 1 1 2 2 2 2 3 3 4 4 4 4 5 5 5]; % 标记每个新分组的起始位置(第一个元素肯定是起始,后面元素和前一个不同时标记为起始) group_starts = [1, diff(V1) ~= 0]; % 先生成全局递增计数 global_counts = cumsum(group_starts); % 把全局计数转换为每个分组内的相对计数(从1开始递增) V2 = global_counts - cumsum(group_starts .* (global_counts - 1));
运行后得到的V2就是你要的[1 2 3 1 2 3 4 1 2 1 2 3 4 1 2 3],完美匹配需求。而且不管V1里元素重复1次还是6次,这个逻辑都能直接适配。
方法二:结合unique+arrayfun(类似repmat的拼接思路)
如果你更倾向于先拆分每个分组再拼接的思路,这个方法很直观:
V1 = [1 1 1 2 2 2 2 3 3 4 4 4 4 5 5 5]; % 获取V1里的唯一元素(保持原顺序)和每个元素的出现次数 [~, ~, idx] = unique(V1, 'stable'); group_lengths = histcounts(idx, length(unique(V1, 'stable'))); % 给每个分组生成1到n的序列,再拼接成最终向量 V2 = cell2mat(arrayfun(@(n) 1:n, group_lengths, 'UniformOutput', false));
这里的arrayfun其实就是替我们完成了“每个分组生成递增序列”的操作,然后用cell2mat把所有小序列拼起来,本质和用repmat生成每个组再拼接是一个逻辑,但写法更简洁。
方法三:用rle函数(有图像处理工具箱的话首选)
如果你的MATLAB装了图像处理工具箱,rle函数能直接帮我们提取连续重复元素的长度,一步到位:
V1 = [1 1 1 2 2 2 2 3 3 4 4 4 4 5 5 5]; % 获取连续重复的元素值和对应的长度 [~, group_lengths] = rle(V1); % 生成每个分组的递增序列并拼接 V2 = cell2mat(arrayfun(@(n) 1:n, group_lengths, 'UniformOutput', false));
这个方法最容易理解,代码也最短,有工具箱的话强烈推荐。
小总结
- 追求性能和无依赖选方法一,纯向量运算速度最快;
- 喜欢直观拼接思路选方法二,不用循环也能实现类似repmat的效果;
- 有图像处理工具箱直接用方法三,代码最简洁。
这些方法都能完美处理V1中元素重复1到6次的场景,完全满足你的需求~
内容的提问来源于stack exchange,提问作者PyjamaNinja
相关产品推荐
相关产品推荐

