Julia:在矩阵的行上循环(或者不循环)



假设我有一个类似的字符串向量

julia> R = ["ABC","DEF"]
2-element Vector{String}:
"ABC"
"DEF"

现在,我复制元素以形成2*2矩阵:

julia> x = [R R]
2×2 Matrix{String}:
"ABC"  "ABC"
"DEF"  "DEF"

我想要实现的是将矩阵中每一行的字符串连接起来。我能想到的最好的是

julia> [join(x[i,:]) for i in 1:length(x)÷2]
2-element Vector{String}:
"ABCABC"
"DEFDEF"

这给出了期望的结果。

是否有其他解决方案(没有显式循环(?我试图找到一个有效的广播语法,但失败了。

(我试过的另一个想法是

julia> x = [R,R]
2-element Vector{Vector{String}}:
["ABC", "DEF"]
["ABC", "DEF"]
julia> join.(x)
2-element Vector{String}:
"ABCDEF"
"ABCDEF"

其为";"更简单";但显然没有给出期望的结果。(

我最终得到了几个将函数应用于矩阵的的选项:

julia> x = ["ABC" "ABC"; "DEF" "DEF"]
2×2 Matrix{String}:
"ABC"  "ABC"
"DEF"  "DEF"

1.使用mapslices进行类似synatax的映射

您正在寻找的函数可能是mapslices(f, A; dims):

julia> mapslices(join, x; dims=[2])
2×1 Matrix{String}:
"ABCABC"
"DEFDEF"

这是一个";地图";呼吁";切片";沿着dims给出的维度。

2.使用eachrow的广播语法

eachrow(A::AbstractVecOrMat)在矩阵的行上创建一个迭代器,为每个行返回数组视图。

julia> join.(eachrow(x))
2-element Vector{String}:
"ABCABC"
"DEFDEF"

3.组合普通mapeachrow

julia> map(join, eachrow(x))
2-element Vector{String}:
"ABCABC"
"DEFDEF"

在使用BenchmarkTools:的100x100随机阵列上,这三种方法的性能似乎是相同的

方法性能
1。@btime mapslices(join, x; dims=[2])1.379毫秒(21935个分配:4.92 MiB(
2。@btime join.(eachrow(x))1.296毫秒(21206个分配:4.82 MiB(
3。@btime map(join, eachrow(x))1.294毫秒(21304个分配:4.82 MiB(

正如你在评论中所说,你从R开始,形成x来获得你想要的东西是没有意义的,只需直接重复R的元素:

julia> repeat.(R, 2) == join.(eachrow([R R]))
true
julia> @btime repeat.($R, 2);
61.283 ns (3 allocations: 128 bytes)
julia> @btime join.(eachrow([$R $R]));
354.392 ns (11 allocations: 704 bytes)

在这种情况下,它分配大约四分之一,速度快5倍。

编辑后添加了一个更接近另一个答案的基准-长度为3个随机字符串的100元素向量:

julia> using Random
julia> R = [randstring(3) for _ ∈ 1:100];
julia> @btime join.(eachrow([$R for _ ∈ 1:100]));
1.607 ms (1103 allocations: 138.62 KiB)
julia> @btime repeat.($R, 100);
43.497 μs (101 allocations: 33.69 KiB)

因此,这里我们在时序上有40倍的差异(尽管现在不太清楚该基准什么,因为除了基准x的不同行的级联之外,人们还可以想出不同的方法来从R构建具有不同效率水平的x(

相关内容

最新更新