数组拼接问题求教


#1

目的:
新建一个空数组,将循环中生成的数组追加进来,希望是水平追加(hcat),循环结束后生成二维数组。
希望得到的数组为:
2 3 4 3 4 5 4 5 6
5 6 7 6 7 8 7 8 9
8 9 10 9 10 11 10 11 12
#--------------------------------------------
a = Array{Float64, 2}[]
b = [1 2 3; 4 5 6; 7 8 9]
for i = 1:3
global b .+= 1
push!(a,b)
end
a
#--------------------------------------------
代码生成的类型是vector{array{float64,2}}
并且是按列追加的
1111
请问应该怎么修改?


#2
julia> b = [1 2 3; 4 5 6; 7 8 9];

julia> a = similar(b, size(b, 1), 3size(b, 2));

julia> for i in 1:3
           a[:, 3(i-1)+1:3i] .= b .+ i
       end

julia> a
3×9 Array{Int64,2}:
 2  3   4  3   4   5   4   5   6
 5  6   7  6   7   8   7   8   9
 8  9  10  9  10  11  10  11  12

这样避免多次分配内存。


#3

这个方法不错,学习了,非常感谢您的帮助!


#4

one-line-fighter: mapreduce(x->b.+x, hcat, 1:3)

julia> function foo(a)
         a = similar(b, size(b, 1), 3size(b, 2));
         for i in 1:3
           a[:,3(i-1)+1:3i] .= b .+ i
         end
         a
       end
foo (generic function with 3 methods)

julia> bar(b) = mapreduce(x->b.+x, hcat, 1:3)
bar (generic function with 1 method)

julia> @btime foo($b)
  3.823 μs (28 allocations: 1.17 KiB)
3×9 Array{Int64,2}:
 2  3   4  3   4   5   4   5   6
 5  6   7  6   7   8   7   8   9
 8  9  10  9  10  11  10  11  12

julia> @btime bar($b)
  241.953 ns (8 allocations: 1.09 KiB)
3×9 Array{Int64,2}:
 2  3   4  3   4   5   4   5   6
 5  6   7  6   7   8   7   8   9
 8  9  10  9  10  11  10  11  12

#5

不知道 mapreduce 为什么更快,1.0 有新的优化?我都怀疑 benchmark 做错了。。


#6

多谢多谢,你们都太牛了
向你们学习


#7

写错了

应该是 b

julia> function foo(b)
           a = similar(b, size(b, 1), 3size(b, 2));
           for i in 1:3
               a[:,3(i-1)+1:3i] .= b .+ i
           end
           a
       end
foo (generic function with 1 method)

julia> @btime foo(b)
  108.884 ns (1 allocation: 336 bytes)
3×9 Array{Int64,2}:
 2  3   4  3   4   5   4   5   6
 5  6   7  6   7   8   7   8   9
 8  9  10  9  10  11  10  11  12

julia> @btime bar(b)
  471.353 ns (9 allocations: 1.13 KiB)
3×9 Array{Int64,2}:
 2  3   4  3   4   5   4   5   6
 5  6   7  6   7   8   7   8   9
 8  9  10  9  10  11  10  11  12

julia> @btime foo($b)
  101.058 ns (1 allocation: 336 bytes)
3×9 Array{Int64,2}:
 2  3   4  3   4   5   4   5   6
 5  6   7  6   7   8   7   8   9
 8  9  10  9  10  11  10  11  12

julia> @btime bar($b)
  287.423 ns (8 allocations: 1.09 KiB)
3×9 Array{Int64,2}:
 2  3   4  3   4   5   4   5   6
 5  6   7  6   7   8   7   8   9
 8  9  10  9  10  11  10  11  12

话说这个 $b 代表是传引用吗?


#8

加了$速度为啥会快些,foo($b) 不就是foo([1 2 3;4 5 6; 7 8 9])的意思吗?


#9

阿哈😄 还真是写错了,我就感觉这个benchmark结果不太对劲


#10

@btime 会跑很多次求平均,$ 是为了避免每次都重新初始化输入变量


#11

谢谢指导,下午我将这些方法用到自己的程序中


#12

哈哈,完全没想过别的。习惯写for循环了。:smile: