2017-01-16 31 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]