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