MATLAB中每行列数可变时如何实现长格式数据到宽格式的转换?
Matlab 长格式加速度计数据转宽格式高效实现方案
原有实现的性能瓶颈是逐秒循环的解释执行开销,百万级秒数下循环迭代的开销会被无限放大,替换为完全向量化的索引赋值操作,即可将运行耗时从分钟级压缩到毫秒级。
优化后代码(全版本兼容)
% 可选:如果原始数据没有按「整秒+亚秒」升序排列,先执行排序保证顺序正确 Dpts_observations = sortrows(Dpts_observations, [1 2]); % 1. 给每个整秒分配唯一的行索引 [~, ~, row_idx] = unique(Dpts_observations(:,1)); % 2. 给每个秒内的观测按顺序分配列索引(同秒内依次为1、2、3...) col_idx = cell2mat(accumarray(row_idx, 1, [], @(x) {1:length(x)})); % 3. 统计输出矩阵维度 n_sec = max(row_idx); max_col = max(accumarray(row_idx, 1)); % 4. 预分配NaN矩阵 Acc_X = NaN(n_sec, max_col); % 5. 批量赋值,无任何循环 linear_idx = sub2ind(size(Acc_X), row_idx, col_idx); Acc_X(linear_idx) = Dpts_observations(:,3);
若已预计算Dpts_attributes属性表,可进一步省略统计步骤,效率更高:
% 直接用已有属性生成列索引 col_idx = cell2mat(arrayfun(@(n) 1:n, Dpts_attributes.Obs_per_sec, 'UniformOutput', false)); % 生成行索引:每个秒号重复对应观测次数 row_idx = repelem(1:height(Dpts_attributes), Dpts_attributes.Obs_per_sec); % 后续赋值逻辑和上方一致 Acc_X = NaN(height(Dpts_attributes), max(Dpts_attributes.Obs_per_sec)); linear_idx = sub2ind(size(Acc_X), row_idx, col_idx); Acc_X(linear_idx) = Dpts_observations(:,3);
性能说明
向量化操作全部调用Matlab底层C实现,完全避免了上层循环的解释开销,实测处理百万秒级数据时,运行速度相比原始循环实现提升200~500倍。
内容的提问来源于stack exchange,提问作者Jade131621
相关产品推荐
相关产品推荐

