我试图将(x,y)点分配给非均匀矩形网格的单元格。简单来说,我将网格定义为排序的非等距数组
xGrid = [x1, x2, x3, x4];
以及位于x
和x1
之间的数字x4
数组。对于每个x
,我想在xGrid
找到它的位置,即i
xGrid(i) <= xi <= xGrid(i+1)
有没有比arrayfun(@(x) find(xGrid <= x, 1, 'last'), x)
更好(更快/更简单)的方法?
答案 0 :(得分:3)
您正在寻找histc
的第二个输出:
[~,where] = histc(x, xGrid)
这将返回数组where
,使xGrid(where(i)) <= x(i) < xGrid(where(i)+1)
成立。
xGrid = [2,4,6,8,10];
x = [3,5,6,9,11];
[~,where] = histc(x, xGrid)
产生以下输出:
where =
1 2 3 4 0
如果你想要xGrid(where(i)) < x(i) <= xGrid(where(i)+1)
,你需要做一些否定价值的技巧:
[~,where] = histc(-x,-flip(xGrid));
where(where~=0) = numel(xGrid)-where(where~=0)
这会产生:
where =
1 2 2 4 0
因为x(3)==6
现在计算的是第二个时间间隔(4,6]
,而不是之前的[6,8)
。
答案 1 :(得分:2)
如果x
是一列,这可能有帮助
xg1=meshgrid(xGrid,1:length(x));
xg2=ndgrid(x,1:length(xGrid));
[~,I]=min(floor(abs(xg1-xg2)),[],2);
或单行实现
[~,I]=min(floor(abs(meshgrid(xGrid,1:length(x))-ndgrid(x,1:length(xGrid)))),[],2);
示例:xGrid=[1 2 3 4 5], x=[2.5; 1.3; 1.7; 4.8; 3.3]
结果:
I =
2
1
1
4
3
答案 2 :(得分:2)
看看这是否适合你 -
matches = bsxfun(@le,xGrid(1:end-1),x(:)) & bsxfun(@ge,xGrid(2:end),x(:))
[valid,pos] = max(cumsum(matches,2),[],2)
pos = pos.*(valid~=0)
示例运行 -
xGrid =
5 2 1 6 8 9 2 1 6
x =
3 7 14
pos =
8
4
0
示例运行说明 -
x的第一个元素,3
位于...1 6
的最后一个,xGrid(i) <= xi <= xGrid(i+1)
后端的标准为 xGrid
,1
1}}位于第8位,因此输出pos
的第一个元素是8
。第二个元素7
会继续,6 and 8
位于6
之间,xGrid
位于4
的第四位,因此输出的第二个元素是{{} 1}}。对于第三个元素14
,它找不到符合 xGrid(i) <= xi <= xGrid(i+1)
标准的邻居,因此输出为0
。
答案 3 :(得分:2)
使用bsxfun
进行比较并利用find
- 类似max
第二个输出的功能:
xGrid = [2 4 6 8]; %// example data
x = [3 6 5.5 10 -10]; %// example data
comp = bsxfun(@gt, xGrid(:), x(:).'); %'// see if "x" > "xGrid"
[~, result] = max(comp, [], 1); %// index of first "xGrid" that exceeds each "x"
result = result-1; %// subtract 1 to find the last "xGrid" that is <= "x"
此方法为0
的值x
提供了xGrid
。使用上面的示例值,
result =
1 3 2 0 0