2017-01-16 71 views
2

假設我有一個一維數組,像這樣:乘以independenly繪製隨機數的陣列的一些成員

julia> myarray = ones(6) 
6-element Array{Float64,1}: 
1.0 
1.0 
1.0 
1.0 
1.0 
1.0 

使一個掩模,將選擇一些元件,在這個例子中,第一和第二元件:

julia> mymask = [true; true; false; false; false; false;] 
6-element Array{Bool,1}: 
    true 
    true 
false 
false 
false 
false 

現在我想乘只能由來自同一分佈中抽取的隨機數的第一和第二元素,並將結果保存在舊的陣列。但是,這將由相同值乘以他們:

julia> myarray[mymask] = myarray[mymask] * rand(Normal(20,5)) 
julia> myarray 
6-element Array{Float64,1}: 
16.5642 
16.5642 
    1.0 
    1.0 
    1.0 
    1.0 

我的下一個想法是嘗試myarray[mymask] = myarray[mymask] * rand(Normal(20,5),2)但它給出了一個錯誤。

回答

3

在多行,以下工作成本:

function mularray!(myarray,mymask) 
    maskpos = find(mymask) 
    myrand = rand(Normal(20,5),length(maskpos)) 
    for i=1:length(maskpos) 
    myarray[maskpos[i]] *= myrand[i] 
    end 
end 

隨着所需要的操作由

julia> mularray!(myarray,mymask) 
julia> myarray 
6-element Array{Float64,1}: 
22.1761 
20.836 
    1.0 
    1.0 
    1.0 
    1.0 

完成其優勢在於速度(以較短解決方案的兩倍多爲基準),或許可讀性(對於som e讀者),但可能對其他變異操作具有靈活性。

+1

只有在版本0.6出現之前,速度優勢纔會到來嗎?然後'。*'將會融合。 – DNF

+0

這確實比其他解決方案更快,所以我選擇它。不過,我很好奇。像這樣的for循環可能是我最終做的事情留給自己的設備。我原以爲這不是最快的方法。另外,「!」是什麼在函數定義中是什麼意思? –

+0

感嘆號僅僅是[Julia style convention](http://docs.julialang.org/zh/release-0.5/manual/style-guide/#append-to-names-of-functions-that-modify-他們的論點)。它表明函數修改了一個或多個參數。 –

5

你可以讓你的乘法明確的elementwise:

julia> myarray[mymask] .*= rand(Normal(20,5), size(myarray[mymask])); 

julia> myarray 
6-element Array{Float64,1}: 
24.1747 
12.6375 
    1.0 
    1.0 
    1.0 
    1.0 
+0

致謝分配這種方式非常好,我選擇了另一個,因爲它在我的機器上速度更快。 –

+0

@BenS。作爲對未來的點頭,注意向量化乘法在Julia v0.6中可能會比目前的v0.5更快。如果當你將代碼轉換到v0.6時,我建議你重試DSM的建議,因爲你的代碼速度可能會改變。 –

0

由於屏蔽的值是布爾,以下方法可以用來

for i in eachindex(arr) 
    mask[i] && (arr[i] *= rand(Normal(20,5))) 
end 

它相當於

for i in eachindex(arr) 
    if mask[i] 
     arr[i] *= rand(Normal(20, 5)) 
    end 
end 

利用這種方法,就可以避免arr[mask]