给定一个矩阵m = [10i+j for i=1:3, j=1:4]
,我可以通过切割矩阵迭代它的行:
for i=1:size(m,1)
print(m[i,:])
end
Run Code Online (Sandbox Code Playgroud)
这是唯一的可能吗?这是推荐的方式吗?
那么理解呢?切片是否只能迭代矩阵的行?
[ sum(m[i,:]) for i=1:size(m,1) ]
Run Code Online (Sandbox Code Playgroud)
tho*_*oly 51
您自己列出的解决方案,以及mapslices
两者都可以正常工作.但是,如果通过"推荐"你真正的意思是"高性能",那么最好的答案是:不要遍历行.
问题在于,由于数组以列主要顺序存储,对于除小矩阵以外的任何其他内容,如果以行主顺序遍历数组,则最终会导致缓存命中率较低.
正如一篇优秀的博客文章所指出的那样,如果你想总结一下行,你最好的办法就是这样做:
msum = zeros(eltype(m), size(m, 1))
for j = 1:size(m,2)
for i = 1:size(m,1)
msum[i] += m[i,j]
end
end
Run Code Online (Sandbox Code Playgroud)
我们遍历两者m
并msum
以其本机存储顺序遍历,因此每次加载缓存行时我们都使用所有值,产生的缓存命中率为1.您可能会天真地认为最好以行主顺序遍历它并累积结果到一个tmp
变量,但在任何现代机器上,缓存未命中比msum[i]
查找要昂贵得多.
Julia的许多内部算法都采用了一个region
参数,比如sum(m, 2)
,为你处理这个问题.
从Julia 1.1开始,有迭代器实用程序可用于迭代矩阵的列或行。要遍历行:
M = [1 2 3; 4 5 6; 7 8 9]
for row in eachrow(af)
println(row)
end
Run Code Online (Sandbox Code Playgroud)
将输出:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
Run Code Online (Sandbox Code Playgroud)