2010-02-24 47 views
2
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.|] 

hello-如何根據另一個數組中的值來平均一個數組中的元素?

我試圖寫一個函數,採用2門陣列(sortedArray和sortedArrayRanks),並返回一個輸出陣列如下面的一個。在這個例子中的映射函數將在sortedArrayRanks中使用2,3,4和5,並且看到它們在sortedArray中都具有相同的值,而是用輸出數組中的所有數字替換它們的平均值(這是3.5 )

讓我感到沮喪的是,是否使用遞歸或命令式循環構造,如循環遍歷排序數組,並查看一個項是否與之前的項相同,然後如果匹配,請檢查它之前的項等等,這怎麼解決?謝謝!

+2

@Foredecker,你爲什麼添加該標籤時沒有任何問題的標記是作業? – Dykam 2010-02-24 19:53:08

回答

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支持相等比較的元素。

+0

這是非常漂亮的代碼。愛它。做得好。 – 2010-02-24 20:03:53

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|] 
相關問題