更新:为了完整起见,我在测试套件中添加了 Matt B. 的出色解决方案(我还强制 f4 中的 transpose 生成一个新矩阵而不是惰性视图)。
这里有一些不同的方法(你的基本情况是f0):
f0(x) = [ i[2] for i in findmax(x, dims = 2)[2]][:,1]
f1(x) = getindex.(argmax(x, dims=2), 2)
f2(x) = [ argmax(vec(x[n,:])) for n = 1:size(x,1) ]
f3(x) = [ argmax(vec(view(x, n, :))) for n = 1:size(x,1) ]
f4(x) = begin ; xt = Matrix{Float64}(transpose(x)) ; [ argmax(view(xt, :, k)) for k = 1:size(xt,2) ] ; end
f5(x) = map(argmax, eachrow(x))
使用BenchmarkTools我们可以检查每个的效率(我设置了x = rand(100, 200)):
julia> @btime f0($x);
76.846 μs (13 allocations: 4.64 KiB)
julia> @btime f1($x);
76.594 μs (11 allocations: 3.75 KiB)
julia> @btime f2($x);
53.433 μs (103 allocations: 177.48 KiB)
julia> @btime f3($x);
43.477 μs (3 allocations: 944 bytes)
julia> @btime f4($x);
73.435 μs (6 allocations: 157.27 KiB)
julia> @btime f5($x);
43.900 μs (4 allocations: 960 bytes)
所以 Matt 的方法是相当明显的赢家,因为它似乎只是我的 f3 的语法更简洁的版本(两者可能编译成非常相似的东西,但我认为检查它会有点过分)。
我希望f4 可能有优势,尽管通过实例化transpose 创建了临时的,因为它可以对矩阵的列而不是行进行操作(Julia 是一种列主要语言,因此操作on columns 总是会更快,因为元素在内存中是同步的)。但这似乎不足以克服暂时的劣势。
注意,如果你想要完整的CartesianIndex,即每行中最大值的行和列索引,那么显然合适的解决方案就是argmax(x, dims=2)。