Julia 中两个向量的笛卡尔积
Cartesian product of two vectors in Julia
我有两个向量 x
和 y
,长度分别为 n 和 p。有没有内置的方法来创建一个 np x 2 矩阵,它是
x[1] y[1]
x[1] y[2]
...
x[1] y[p]
x[2] y[1]
...
x[n] y[p]
我可以使用嵌套的 for 循环来做到这一点,但我正在寻找内置函数(如果存在)。
我可能会这样做:
julia> x = [1, 2, 3, 4];
julia> y = [9, 8, 7];
julia> [repeat(x, inner=[size(y,1)]) repeat(y, outer=[size(x,1)])]
12x2 Array{Int64,2}:
1 9
1 8
1 7
2 9
2 8
2 7
3 9
3 8
3 7
4 9
4 8
4 7
您可能还想看看 Iterators.j -- 特别是 product
函数。
Julia 在嵌套循环中通常非常快,所以如果它们为您正常工作,您可能应该检查性能,也许只是坚持使用它。
其他选项是使用 repmat(这个比使用 repeat 快一点):
[repmat(x,1,length(y))'[:] repmat(y,length(x),1)[:]]
对这两种方法进行了一些快速测试:
x=rand(1000)
y=rand(1000)
function withrepeat(x,y)
[repeat(x, inner=[size(y,1)]) repeat(y, outer=[size(x,1)])]
end
function withrepmat(x,y)
[repmat(x,1,length(y))'[:] repmat(y,length(x),1)[:]]
end
withrepeat(x,y)
elapsed time: 0.21556302 seconds (95986112 bytes allocated)
with repmat(x,y)
elapsed time: 0.075604488 seconds (56000560 bytes allocated)
不确定为什么会有如此大的差异,但我认为仍有改进的余地。
Iterators.jl 包里面的 product 函数没试过。
这里还有更多信息:https://groups.google.com/forum/#!topic/julia-users/dtl--SyFgwY
希望对您有所帮助。
尝试了几个嵌套循环,确实更快:
function withloops (x,y)
leny=length(y)
lenx=length(x)
m=leny*lenx
OUT = zeros(Float64, m,2)
c=1
for i = 1:lenx
for j = 1:leny
OUT[c,1] = x[i]
OUT[c,2] = y[j]
c+=1
end
end
return OUT
end
并且,对于 x
和 y
的相同 rand(1000)
。
withloops(x,y)
elapsed time: 0.011350679 seconds (16000128 bytes allocated)
这是在 IterTools 模块(取代 Iterators 模块)中提供的。
取自https://github.com/JuliaCollections/IterTools.jl
Iterate over all combinations in the cartesian product of the inputs.
Example:
using IterTools
for p in product(1:3,1:2)
@show p
end
p = (1,1)
p = (2,1)
p = (3,1)
p = (1,2)
p = (2,2)
p = (3,2)
至少在 Julia 1.3 中,有一个内置函数 Iterators.product,所以
Iterators.product(a, b) |> collect
应该可以解决问题。
我有两个向量 x
和 y
,长度分别为 n 和 p。有没有内置的方法来创建一个 np x 2 矩阵,它是
x[1] y[1]
x[1] y[2]
...
x[1] y[p]
x[2] y[1]
...
x[n] y[p]
我可以使用嵌套的 for 循环来做到这一点,但我正在寻找内置函数(如果存在)。
我可能会这样做:
julia> x = [1, 2, 3, 4];
julia> y = [9, 8, 7];
julia> [repeat(x, inner=[size(y,1)]) repeat(y, outer=[size(x,1)])]
12x2 Array{Int64,2}:
1 9
1 8
1 7
2 9
2 8
2 7
3 9
3 8
3 7
4 9
4 8
4 7
您可能还想看看 Iterators.j -- 特别是 product
函数。
Julia 在嵌套循环中通常非常快,所以如果它们为您正常工作,您可能应该检查性能,也许只是坚持使用它。
其他选项是使用 repmat(这个比使用 repeat 快一点):
[repmat(x,1,length(y))'[:] repmat(y,length(x),1)[:]]
对这两种方法进行了一些快速测试:
x=rand(1000)
y=rand(1000)
function withrepeat(x,y)
[repeat(x, inner=[size(y,1)]) repeat(y, outer=[size(x,1)])]
end
function withrepmat(x,y)
[repmat(x,1,length(y))'[:] repmat(y,length(x),1)[:]]
end
withrepeat(x,y)
elapsed time: 0.21556302 seconds (95986112 bytes allocated)
with repmat(x,y)
elapsed time: 0.075604488 seconds (56000560 bytes allocated)
不确定为什么会有如此大的差异,但我认为仍有改进的余地。 Iterators.jl 包里面的 product 函数没试过。
这里还有更多信息:https://groups.google.com/forum/#!topic/julia-users/dtl--SyFgwY
希望对您有所帮助。
尝试了几个嵌套循环,确实更快:
function withloops (x,y)
leny=length(y)
lenx=length(x)
m=leny*lenx
OUT = zeros(Float64, m,2)
c=1
for i = 1:lenx
for j = 1:leny
OUT[c,1] = x[i]
OUT[c,2] = y[j]
c+=1
end
end
return OUT
end
并且,对于 x
和 y
的相同 rand(1000)
。
withloops(x,y)
elapsed time: 0.011350679 seconds (16000128 bytes allocated)
这是在 IterTools 模块(取代 Iterators 模块)中提供的。
取自https://github.com/JuliaCollections/IterTools.jl
Iterate over all combinations in the cartesian product of the inputs.
Example:
using IterTools for p in product(1:3,1:2) @show p end p = (1,1) p = (2,1) p = (3,1) p = (1,2) p = (2,2) p = (3,2)
至少在 Julia 1.3 中,有一个内置函数 Iterators.product,所以
Iterators.product(a, b) |> collect
应该可以解决问题。