let tiedArray = [|9.4;1.2;-3.4;-3.4;-3.4;-3.4;-10.0|];
let sortedArray = [|-10.0;-3.4;-3.4;-3.4;-3.4;1.2;9.4|];
let sortedArrayRanks = [|1.;2.;3.;4.;5.;6.;7.|];
let desired_ranked_array = [|1.;3.5;3.5;3.5;3.5;6.;7.|]
您好 -
我正在尝试编写一个带有2个数组(sortedArray和sortedArrayRanks)的函数,并返回一个如下所示的输出数组。此示例中的映射函数将在sortedArrayRanks中使用2,3,4和5,并且看到它们在sortedArray中都具有相同的值,而是将它们中的所有这些数字替换为它们的平均值(即3.5) )
让我兴奋的是,是使用递归还是命令性循环结构,比如循环遍历排序数组,并查看项目是否与之前的项目相同,然后如果匹配,请检查前面的项目,等等这怎么解决?谢谢!
答案 0 :(得分:2)
这与F# How to Percentile Rank An Array of Doubles?非常相似。以下是我对该问题的回答的变体:
let rank arr (ranks:float[]) =
let rev = Array.rev arr
let len = Array.length arr
let first x = Array.findIndex (fun y -> y = x) arr
let last x = len - (Array.findIndex (fun y -> y = x) rev) - 1
let avgR x = ranks.[(first x) .. (last x)] |> Array.average
Array.map avgR arr
这假定arr
已排序,arr
中的元素支持相等比较。
答案 1 :(得分:0)
你可以:
记下那个算法作为剧本:
let f sortedArray sortedArrayRanks =
[|
for v,xs in Array.zip sortedArray sortedArrayRanks |> Seq.groupBy (fun (v,r) -> v) do
let n,r = Seq.fold (fun (n,r) (_,r') -> (n+1,r+r')) (0,0.) xs
let r = r/(float n)
for i in 1..n do yield r
|]
> f [|-10.0;-3.4;-3.4;-3.4;-3.4;1.2;9.4|] [|1.;2.;3.;4.;5.;6.;7.|];;
val it : float [] = [|1.0; 3.5; 3.5; 3.5; 3.5; 6.0; 7.0|]