Julia 将数组的一些成员乘以独立绘制的随机数

Julia 将数组的一些成员乘以独立绘制的随机数,julia,Julia,假设我有一个1D数组,如下所示: 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

假设我有一个1D数组,如下所示:

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
现在我只想将第一个和第二个元素乘以从相同分布中提取的随机数,并将结果保存在旧数组上。但这会将它们乘以相同的值:


我的下一个想法是尝试
myarray[mymask]=myarray[mymask]*rand(Normal(20,5),2)
,但它给出了一个错误

您可以将乘法显式元素化:

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   

以更多线路的成本,以下工程:

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   

优势在于速度(基准测试为较短解决方案的2倍以上),可能是可读性(对于某些读者),但可能是其他变异操作的灵活性。

由于掩码的值是布尔值,因此可以使用以下方法

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]

在0.6版本出现之前,速度优势不会一直存在吗?然后,
*
将融合。这确实比其他解决方案快,所以我选择它。不过我很好奇。类似这样的for循环可能是我最终将要做的事情,留给我自己的设备。我本以为这不是最快的方法。另外,函数定义中的“!”是什么意思?感叹号只是一个符号。它表示函数修改了一个或多个参数。这种避免不必要分配的循环解决方案在Julia中非常典型。通过避免“查找”并使用“mymask”的“和”而不是“长度”,可以删除另一个分配。可能会压缩更多的性能。由于这种方式的简洁性非常好,我选择了另一种,因为它在我的机器上速度更快。@BenS。作为对未来的展望,请注意向量化乘法在Julia v0.6中可能比目前在v0.5中更快。如果您将代码转换到v0.6,我建议您重试DSM的建议,因为您的代码速度可能会改变。
for i in eachindex(arr)
    if mask[i]
        arr[i] *= rand(Normal(20, 5))
    end
end