我需要爲可變數量的數組有效實施笛卡爾乘積。函數參數的就地更新
我曾嘗試product
功能從Iterators.jl
,但缺乏的表現。
我是一名蟒蛇黑客,使用sklearn的this function,並且使用它獲得了良好的性能。
我試圖編寫一個Julia版本的這個函數,但是不能產生和python函數一樣的結果。
我的代碼是:
function my_repeat(a, n)
# mimics numpy.repeat
m = size(a, 1)
out = Array(eltype(a), n * m)
out[1:n] = a[1]
for i=2:m
out[(i-1)*n+1:i*n] = a[i]
end
return out
end
function cartesian(arrs; out=None)
dtype = eltype(arrs[1])
n = prod([size(i, 1) for i in arrs])
if is(out, None)
out = Array(dtype, n, length(arrs))
end
m = int(n/size(arrs[1], 1))
out[:, 1] = my_repeat(arrs[1], m)
if length(arrs[2:]) > 0
cartesian(arrs[2:], out=out[1:m, 2:])
for j = 1:size(arrs[1], 1)-1
out[(j*m + 1):(j+1)*m, 2:] = out[1:m, 2:]
end
end
return out
end
我測試了以下內容:
aa = ([1, 2, 3], [4, 5], [6, 7])
cartesian(aa)
返回值是:
12x3 Array{Float64,2}:
1.0 9.88131e-324 2.13149e-314
1.0 2.76235e-318 2.13149e-314
1.0 9.88131e-324 2.13676e-314
1.0 9.88131e-324 2.13676e-314
2.0 9.88131e-324 2.13149e-314
2.0 2.76235e-318 2.13149e-314
2.0 9.88131e-324 2.13676e-314
2.0 9.88131e-324 2.13676e-314
3.0 9.88131e-324 2.13149e-314
3.0 2.76235e-318 2.13149e-314
3.0 9.88131e-324 2.13676e-314
3.0 9.88131e-324 2.13676e-314
我認爲,這裏的問題是,當我使用這一行:cartesian(arrs[2:], out=out[1:m, 2:])
,關鍵字參數out
沒有更新就地在復發來電。
可以看出,我已經做了這個函數的Python版本的非常天真的翻譯(請參閱上面的鏈接)。很可能存在內部語言差異導致翻譯不可行的情況。我不認爲這是正確的,因爲從朱莉婭文檔的functions節本帖:
朱莉婭函數參數遵循有時也被稱爲公約「傳址共享」,這意味着值不會被複制當它們傳遞給函數時。函數參數本身作爲新的變量綁定(可以引用值的新位置),但它們引用的值與傳遞的值相同。對函數內的可變值(例如數組)的修改對調用者來說是可見的。這與Scheme中的行爲相同,大多數Lisp,Python,Ruby和Perl等動態語言。
我該如何使這個(或等效)函數在Julia中工作?
由於'out'的類型不能被編譯器推斷(它可能是'None'或它可能是一個'Array'),無論你如何處理array-切片。一個更好的方法可能是避免第二個參數的關鍵字(只需將分號改爲逗號)並將其初始化爲Array(eltype(arrs [1]),prod([size(i,1) ]),長度(arrs))'。 – tholy