Matlab中快速获取3D直方图已占用分箱的方法问询
3D数据分箱优化:替代
unique的高效实现 问题背景
拥有一组3D数据,需通过空间离散化分箱减少属性计算量——仅对包含数据点的分箱计算属性,再将结果分配回数据点。当前通过histcounts对各维度单独分箱,再用unique(bins,'rows')提取唯一分箱,但该操作耗时过长,需更高效的实现方案(分箱编号为整数)。
当前实现代码
a5pre=compositions(:,1); a7pre=compositions(:,2); a8pre=compositions(:,3); %% BINNING a5pre_edges=[0,linspace(0.005,0.995,19),1]; a5pre_val=(a5pre_edges(1:end-1) + a5pre_edges(2:end))/2; a5pre_val(1)=0; a5pre_val(end)=1; a7pre_edges=[0,linspace(0.005,0.995,49),1]; a7pre_val=(a7pre_edges(1:end-1) + a7pre_edges(2:end))/2; a7pre_val(1)=0; a7pre_val(end)=1; a8pre_edges=a7pre_edges; a8pre_val=a7pre_val; [~,~,bin1]=histcounts(a5pre,a5pre_edges); [~,~,bin2]=histcounts(a7pre,a7pre_edges); [~,~,bin3]=histcounts(a8pre,a8pre_edges); bins=[bin1,bin2,bin3]; [A,~,C]=unique(bins,'rows','stable'); a5pre=a5pre_val(A(:,1)); a7pre=a7pre_val(A(:,2)); a8pre=a8pre_val(A(:,3));
优化方案
1. 三维箱号编码为一维整数(最优推荐)
利用分箱编号为整数的特性,将三维箱号映射为唯一的一维整数编码,再对一维数组执行unique操作。Matlab对一维数组的处理远快于二维行数组,此方法能大幅提升效率。
根据你的分箱参数:
- a5维度共20个分箱(
a5pre_edges长度为21),箱号范围1~20 - a7、a8维度各50个分箱,箱号范围
1~50
编码公式可保证每个三维箱对应唯一一维整数:
bin_code = bin1 + (bin2 - 1)*20 + (bin3 - 1)*20*50;
修改后的核心代码:
% 原分箱逻辑不变,得到bin1, bin2, bin3后 bin_code = bin1 + (bin2 - 1)*20 + (bin3 - 1)*20*50; [unique_codes, ~, C] = unique(bin_code, 'stable'); % 将一维编码还原为三维箱号 A = zeros(length(unique_codes), 3); A(:,3) = floor((unique_codes - 1)/(20*50)) + 1; remainder = mod(unique_codes - 1, 20*50); A(:,2) = floor(remainder/20) + 1; A(:,1) = mod(remainder, 20) + 1; % 后续赋值逻辑不变 a5pre=a5pre_val(A(:,1)); a7pre=a7pre_val(A(:,2)); a8pre=a8pre_val(A(:,3));
2. 利用histcounts3(Matlab R2019b及以上版本)
若使用较新版本Matlab,可直接用官方优化的histcounts3完成3D分箱,同时获取非空分箱位置,无需手动拆分维度再合并:
edges = {a5pre_edges, a7pre_edges, a8pre_edges}; [N, ~, bin_idx] = histcounts3(compositions, 'Edges', edges); % 获取非空分箱的索引 non_empty_bins = find(N > 0); % 将线性索引转换为三维箱号 [A(:,1), A(:,2), A(:,3)] = ind2sub(size(N), non_empty_bins); % 后续赋值逻辑不变
3. 稀疏矩阵标记法
通过稀疏矩阵快速标记存在数据点的分箱,再提取非零元素的位置,内存占用更低:
% 构建稀疏矩阵,存在数据点的分箱标记为1 S = sparse(bin1, bin2, bin3, 20, 50, 50); % 获取非零元素的三维坐标 [i,j,k] = find(S); A = [i,j,k]; % 后续赋值逻辑不变
性能说明
- 一维编码法在百万级数据点场景下,相比原
unique(bins,'rows')可提升数倍至数十倍速度; histcounts3代码更简洁,是官方优化的3D分箱方案,效率稳定;- 稀疏矩阵法适合分箱总数不极大的场景,内存占用优势明显。
内容的提问来源于stack exchange,提问作者Marc Laub
相关产品推荐
相关产品推荐

