使用 "find" 命令累加值 "without for loops"
Using the "find" command to accumulate values "without for loops"
我将使用 find
从一个矩阵(名为 lag
)中获取索引,然后从另一个矩阵(H
)中对它们的相应值求和。这将需要一个 for
循环。 (矩阵是二维的。)
(此处使用max
来暗示一个通用示例)
D=zeros(max, 1)
for j = 1:max
ind = find(lag==j)
D(j) = sum(H(ind))
end
这是一个4分的例子。点位于 (1,1)、(1,2)、(2,1)、(2,2)。这是地统计学方法的一部分。 H
中计算了所有点之间的距离。 lags
是 H
但向下舍入然后加 1 以将距离与其最接近的整数相关联(称为滞后的分类)。我现在想将每个 lag
的总距离加到矢量 D
.
lag
(4x4) - 存储一般滞后间隔
1 2 2 2
2 1 2 2
2 2 1 2
2 2 2 1
H
(4x4) - 存储点之间的距离
0 1 1 1.414
1 0 1.414 1
1 1.414 0 1
1.414 1 1 0
我可以在没有 for
循环的情况下执行此操作吗?
没有 for
循环就没有好的方法,但是你可以不使用 find
.
D = zeros(N, 1)
for j = 1:N
D(j) = sum(sum((lag == j).*H));
end
lag == j
的结果将是一个 4x4(或更确切地说 NxN)布尔值矩阵,这样 (lag == j).*H
将保留每个滞后的距离,但所有其他元素都为零。对 (lag == j).*H
中的所有元素求和将为 D(j)
.
提供相同的答案
请注意,我已将 max
切换为 N
,因为 max
是内置的 MATLAB 函数。
您可以使用
ulag = unique(lag); %contains [1 2]
D = arrayfun(@(l)sum(H(lag==l)),ulag);
unique(lag)
会将 lag
提取为唯一值,在您的小示例中 [1 2]
。然后 arrayfun
将遍历数组 ulag
,并且对于每个元素 l
它将执行 sum(H(lag==l))
,这正是您想要的:对 [=20= 中的那些元素求和] lag
中对应的元素等于 l
。请注意,这仅在 lag
包含整数时才有效,否则 unique
可能由于机器精度而找不到相同的元素(但从你的问题中我了解到它可能本质上是一个整数)。
另请注意,上面两行也可以写成一条:
D = arrayfun(@(l)sum(H(lag==l)),unique(lag));
我只是觉得分开后可能更容易消化
还要注意,上面利用了 lag
的值从 1 开始到最大值,没有间隙。如果不是这种情况,那么你应该做类似
的事情
D(unique(lag)) = arrayfun(@(l)sum(H(lag==l)),unique(lag));
但在这种情况下,您必须确保 lag
不包含非正值。
这很容易用accumarray
完成:
D = accumarray(lag(:), H(:));
这会为由第一个参数(lag
线性化为列向量)的值定义的每个组累积(求和)第二个参数的值(H
线性化为列向量) .
我将使用 find
从一个矩阵(名为 lag
)中获取索引,然后从另一个矩阵(H
)中对它们的相应值求和。这将需要一个 for
循环。 (矩阵是二维的。)
(此处使用max
来暗示一个通用示例)
D=zeros(max, 1)
for j = 1:max
ind = find(lag==j)
D(j) = sum(H(ind))
end
这是一个4分的例子。点位于 (1,1)、(1,2)、(2,1)、(2,2)。这是地统计学方法的一部分。 H
中计算了所有点之间的距离。 lags
是 H
但向下舍入然后加 1 以将距离与其最接近的整数相关联(称为滞后的分类)。我现在想将每个 lag
的总距离加到矢量 D
.
lag
(4x4) - 存储一般滞后间隔
1 2 2 2
2 1 2 2
2 2 1 2
2 2 2 1
H
(4x4) - 存储点之间的距离
0 1 1 1.414
1 0 1.414 1
1 1.414 0 1
1.414 1 1 0
我可以在没有 for
循环的情况下执行此操作吗?
没有 for
循环就没有好的方法,但是你可以不使用 find
.
D = zeros(N, 1)
for j = 1:N
D(j) = sum(sum((lag == j).*H));
end
lag == j
的结果将是一个 4x4(或更确切地说 NxN)布尔值矩阵,这样 (lag == j).*H
将保留每个滞后的距离,但所有其他元素都为零。对 (lag == j).*H
中的所有元素求和将为 D(j)
.
请注意,我已将 max
切换为 N
,因为 max
是内置的 MATLAB 函数。
您可以使用
ulag = unique(lag); %contains [1 2]
D = arrayfun(@(l)sum(H(lag==l)),ulag);
unique(lag)
会将 lag
提取为唯一值,在您的小示例中 [1 2]
。然后 arrayfun
将遍历数组 ulag
,并且对于每个元素 l
它将执行 sum(H(lag==l))
,这正是您想要的:对 [=20= 中的那些元素求和] lag
中对应的元素等于 l
。请注意,这仅在 lag
包含整数时才有效,否则 unique
可能由于机器精度而找不到相同的元素(但从你的问题中我了解到它可能本质上是一个整数)。
另请注意,上面两行也可以写成一条:
D = arrayfun(@(l)sum(H(lag==l)),unique(lag));
我只是觉得分开后可能更容易消化
还要注意,上面利用了 lag
的值从 1 开始到最大值,没有间隙。如果不是这种情况,那么你应该做类似
D(unique(lag)) = arrayfun(@(l)sum(H(lag==l)),unique(lag));
但在这种情况下,您必须确保 lag
不包含非正值。
这很容易用accumarray
完成:
D = accumarray(lag(:), H(:));
这会为由第一个参数(lag
线性化为列向量)的值定义的每个组累积(求和)第二个参数的值(H
线性化为列向量) .