假设我有n个数组,其中n是一个变量(某个数字大于2,通常小于10)。
每个数组都有k个元素。
我还有一个长度为n的数组,其中包含一组权重,这些权重决定了我如何线性组合所有数组。
我正在尝试创建一个高性能的高阶函数,以便在F#中组合这些数组。
我该如何做到这一点,以便我得到一个函数,它接受一个数组数组(arrs是一个样本),一个权重数组(权重),然后根据权重计算一个加权和?
let weights = [|.6;;.3;.1|]
let arrs = [| [|.0453;.065345;.07566;1.562;356.6|] ;
[|.0873;.075565;.07666;1.562222;3.66|] ;
[|.06753;.075675;.04566;1.452;3.4556|] |]
感谢任何想法。
答案 0 :(得分:6)
这是一个解决方案:
let combine weights arrs =
Array.map2 (fun w -> Array.map ((*) w)) weights arrs
|> Array.reduce (Array.map2 (+))
修改强>
这里有一些(非常需要的)解释这是如何工作的。从逻辑上讲,我们希望执行以下操作:
上面两行就是这样做的。
Array.map2
函数来组合相应的权重和行;我们将它们组合在一起的方法是将行中的每个元素乘以权重,这通过内部Array.map
来实现。Array.map2
,使用(+)
作为组合每个元素的函数。我们将它包装在Array.reduce
中,依次从第一行开始依次将此添加函数应用于每一行。希望这是一个相当优雅的解决问题的方法,尽管无点的风格无疑使得它有点棘手。但请注意,它并不是特别高效;进行就地更新而不是使用map
,map2
和reduce
的每个应用程序创建新数组会更有效。不幸的是,标准库不包含这些操作的良好类似物,这些操作就地工作。但是,创建这样的类似物会相对容易,而且它们的使用方式几乎和我在这里完全相同。
答案 1 :(得分:1)
这样的事情对我有用:
let weights = [|0.6;0.3;0.1|]
let arrs = [| [|0.0453;0.065345;0.07566;1.562;356.6|] ;
[|0.0873;0.075565;0.07666;1.562222;3.66|] ;
[|0.06753;0.075675;0.04566;1.452;3.4556|] |]
let applyWeight x y = x * y
let rotate (arr:'a[][]) =
Array.map (fun y -> (Array.map (fun x -> arr.[x].[y])) [|0..arr.Length - 1|]) [|0..arr.[0].Length - 1|]
let weightedarray = Array.map (fun x -> Array.map(applyWeight (fst x)) (snd x)) (Array.zip weights arrs)
let newarrs = Array.map Array.sum (rotate weightedarray)
printfn "%A" newarrs
顺便说一下..浮点值前面的0是必要的。