You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 12:30:54