2013-11-08 2 views
6

У меня есть облако 3D-точек (XYZ), где Z может быть позицией или энергией. Я хочу, чтобы спроецировать их на 2D поверхности в сетке пм матрица с размерностью (в моей проблеме n = m) таким образом, что каждая ячейка сетки имеет значение максимальной разности Z, в случае Z будучи позиции , или значение суммирования по Z, в случае Z, являющегося энергией.Анализ 3D-облака точек проекцией на 2D-поверхность

Например, в диапазоне 0 <= (x,y) <= 20 есть 500 баллов. Скажем, xy-плоскость имеет n -by- m перегородки, например. -by- ; под которым я подразумеваю как в направлениях x, так и в y, у нас есть 4 раздела с интервалом 5 (чтобы сделать его максимально 20. Теперь каждая из этих ячеек должна иметь значение суммирования или максимальную разницу в значении Z те точки, которые находятся в соответствующем столбце в определенной плоскости х.

Я сделал простой массив XYZ только для испытания следующим образом, где в этом случае, Z обозначает энергию каждой точки.

n=1; 
for i=1:2*round(random('Uniform',1,5)) 
    for j=1:2*round(random('Uniform',1,5)) 
     table(n,:)=[i,j,random('normal',1,1)]; 
     n=n+1; 
    end 
end 

Как это можно сделать без петель?

ответ

3

Примечания:

  1. все это может быть почти один вкладыш с помощью питона панд и методы резки.
  2. Я переписать ваши случайных инициализации облака

Что вы можете сделать, это

  1. раскладка х сетки через meshgrid,
  2. проект облако на х (простой маргинализации)
  3. найти ближайшую точку сетки через поиск kd-tree, т.е. этикетка ваши данные, связывающие каждую точку облачности с узлом сетки
  4. Группируйте данные по метке и оценивайте свою локальную статистику (через accumarray).

Вот рабочий пример:

samples = 500; 
%data extrema 
xl = 0; xr = 1; yl = 0; yr = 1; 

% # grid points 
sz = 20; 
% # new random cloud  
table = [random('Uniform',xl,xr,[samples,1]) , random('Uniform',yr,yl,[samples,1]), random('normal',1,1,[samples,1])]; 

figure; scatter3(table(:,1),table(:,2),table(:,3)); 

% # grid construction 
xx = linspace(xl,xr,sz); yy = linspace(yl,yr,sz); 
[X,Y] = meshgrid(xx,yy); 
grid_centers = [X(:),Y(:)]; 

x = table(:,1); y = table(:,2); 

% # kd-tree 
kdtreeobj = KDTreeSearcher(grid_centers); 
clss = kdtreeobj.knnsearch([x,y]); % # classification 

% # defintion of local statistic 
local_stat = @(x)sum(x) % # for total energy 
% local_stat = @(x)max(x)-min(x) % # for position off-set 

% # data_grouping 
class_stat = accumarray(clss,table(:,3),[],local_stat);  
class_stat_M = reshape(class_stat , size(X)); % # 2D reshaping 

figure; contourf(xx,yy,class_stat_M,20); 

enter image description here enter image description here

4

accumarray функция вполне подходит для такого рода задач.Сначала я определяю пример данных:

table = [ 20*rand(1000,1) 30*rand(1000,1) 40*rand(1000,1)]; % random data 
x_partition = 0:2:20; % partition of x axis 
y_partition = 0:5:30; % partition of y axis 

Я предполагаю, что

  • Три колонны table представляют х, у, г соответственно
  • Ни одна точка не имеет х ниже, чем у первого края ваша сетка или больше, чем последний край, и то же самое для y. То есть, сетка покрывает все точки.
  • Если в корзине нет значений, результат должен быть NaN (если вы хотите получить другое значение заполнения, просто измените последний аргумент accumarray).

Тогда:

L = size(table,1); 
M = length(x_partition); 
N = length(y_partition); 
[~, ii] = max(repmat(table(:,1),1,M) <= repmat(x_partition,L,1),[],2); 
[~, jj] = max(repmat(table(:,2),1,N) <= repmat(y_partition,L,1),[],2); 
ii = ii-1; % by assumption, all values in ii will be at least 2, so we subtract 1 
jj = jj-1; % same for jj 
result_maxdif = accumarray([ii jj], table(:,3), [M-1 N-1], @(v) max(v)-min(v), NaN); 
result_sum = accumarray([ii jj], table(:,3), [M-1 N-1], @sum, NaN); 

Примечания к коду:

  • Ключ получение ii и jj, которые дают индексы х и у бункеров, в которых каждая точка лежит. Для этого я использую repmat. Было бы лучше использовать bsxfun, но он не поддерживает версию с несколькими выходами @max.
  • Результат имеет размер (М-1) × (N-1) (количество бункеров в каждом измерении)
+2

+1 к обоим ответам. Приятно видеть, что 'tankarray' используется умными способами. Существует четкая кривая обучения с 'accumarray', но она открывает двери, как только вы ее снимите. – chappjc

+0

@chappjc Мне нравится, как все эти входные параметры (для аккумулирования), которые я изначально нашел почти бесполезными, оказываются в точности, что мне нужно ;-) –