如何平均 utm 格式的网格参数避免循环
How to average parameters for a grid in utm format avoiding for loops
嗨,我有一个小问题。我在 utm (x,y) 中有 1 秒时间分辨率的 gps 数据,速度为一年,我想对 20m 网格进行速度平均。我的代码有效,但它真的很慢,因为我使用 for 循环来查找与网格匹配的坐标。任何帮助表示赞赏。
亲切的问候马蒂亚斯
%x_d is x coordinate
%Y_d is y coordinate
%x_vec is the xgrid vector definition
%y_vec is the ygrid vector definition
%s is the speed
for i=1:length(vec_x)
for j=1:length(vec_y)
ind = find(x_d<=vec_x(i)+10& x_d>vec_x(i)-10 & y_d<=vec_y(j)+10 & y_d>vec_y(j)-10);
Ad(j,i) = nanmean(s(ind));
end
end
A) 使用逻辑索引,摆脱耗时find
:你的代码
ind = find(x_d<=vec_x(i)+10& x_d>vec_x(i)-10 & y_d<=vec_y(j)+10 & y_d>vec_y(j)-10);
Ad(j,i) = nanmean(s(ind));
等于更快
ix = x_d<=vec_x(i)+10& x_d>vec_x(i)-10 & y_d<=vec_y(j)+10 & y_d>vec_y(j)-10;
Ad(j,i) = nanmean(s(ix));
B) 尝试使用已知的网格大小信息直接访问正确的网格元素。从偏移量和元素大小(20)你可以推断:
ind_x = floor((x_d - min(vec_x))./20) + 1;
ind_y = floor((y_d - min(vec_y))./20) + 1;
然后你会循环遍历你的网格并选择位置。也许这可以通过 arrayfun 来改进。
for i=1:length(vec_x)
for j=1:length(vec_y)
ix = ind_x == i & ind_y == j;
Ad(j,i) = nanmean(s(ix));
end
end
可以使用 MATLAB 的 histcounts
和 accumarray
函数在没有循环的情况下完成。 question/solution 几乎是 的副本,除了可能使用 histcounts
。
histcounts
适用于装箱问题(这是)。 [~,~,x_idx]=histcounts(x_d,x_vec)
告诉您每个 x 坐标在哪个 x-bin 中。与 y_d, y_vec
.
类似
accumarray
适用于对重复索引求和(以避免循环)。下面的调用对每个 bin 的速度值求和,然后应用 @mean
函数对它们进行平均。 0
告诉 accumarray
用零填充空箱。
x_vec = 0:20;
y_vec = 0:20;
x_d = rand(1000,1)*20;
y_d = rand(1000,1)*20;
s = rand(1000,1);
[~,~,x_idx] = histcounts(x_d,x_vec);
[~,~,y_idx] = histcounts(y_d,y_vec);
avg = accumarray([x_idx y_idx],s,[length(x_vec)-1,length(y_vec)-1],@mean,0)
嗨,我有一个小问题。我在 utm (x,y) 中有 1 秒时间分辨率的 gps 数据,速度为一年,我想对 20m 网格进行速度平均。我的代码有效,但它真的很慢,因为我使用 for 循环来查找与网格匹配的坐标。任何帮助表示赞赏。 亲切的问候马蒂亚斯
%x_d is x coordinate
%Y_d is y coordinate
%x_vec is the xgrid vector definition
%y_vec is the ygrid vector definition
%s is the speed
for i=1:length(vec_x)
for j=1:length(vec_y)
ind = find(x_d<=vec_x(i)+10& x_d>vec_x(i)-10 & y_d<=vec_y(j)+10 & y_d>vec_y(j)-10);
Ad(j,i) = nanmean(s(ind));
end
end
A) 使用逻辑索引,摆脱耗时find
:你的代码
ind = find(x_d<=vec_x(i)+10& x_d>vec_x(i)-10 & y_d<=vec_y(j)+10 & y_d>vec_y(j)-10);
Ad(j,i) = nanmean(s(ind));
等于更快
ix = x_d<=vec_x(i)+10& x_d>vec_x(i)-10 & y_d<=vec_y(j)+10 & y_d>vec_y(j)-10;
Ad(j,i) = nanmean(s(ix));
B) 尝试使用已知的网格大小信息直接访问正确的网格元素。从偏移量和元素大小(20)你可以推断:
ind_x = floor((x_d - min(vec_x))./20) + 1;
ind_y = floor((y_d - min(vec_y))./20) + 1;
然后你会循环遍历你的网格并选择位置。也许这可以通过 arrayfun 来改进。
for i=1:length(vec_x)
for j=1:length(vec_y)
ix = ind_x == i & ind_y == j;
Ad(j,i) = nanmean(s(ix));
end
end
可以使用 MATLAB 的 histcounts
和 accumarray
函数在没有循环的情况下完成。 question/solution 几乎是 histcounts
。
histcounts
适用于装箱问题(这是)。 [~,~,x_idx]=histcounts(x_d,x_vec)
告诉您每个 x 坐标在哪个 x-bin 中。与 y_d, y_vec
.
accumarray
适用于对重复索引求和(以避免循环)。下面的调用对每个 bin 的速度值求和,然后应用 @mean
函数对它们进行平均。 0
告诉 accumarray
用零填充空箱。
x_vec = 0:20;
y_vec = 0:20;
x_d = rand(1000,1)*20;
y_d = rand(1000,1)*20;
s = rand(1000,1);
[~,~,x_idx] = histcounts(x_d,x_vec);
[~,~,y_idx] = histcounts(y_d,y_vec);
avg = accumarray([x_idx y_idx],s,[length(x_vec)-1,length(y_vec)-1],@mean,0)