假设我有一个类似的字符串向量
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.组合普通map
和eachrow
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
(