2010-02-24 7 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-Comment calculer la moyenne des éléments d'un tableau en fonction des valeurs d'un autre tableau?

Je suis en train d'écrire une fonction qui prend 2 tableaux (sortedArray et sortedArrayRanks) et retourne un tableau de sortie comme celui ci-dessous. La fonction de mappage dans cet exemple prend 2,3,4 et 5 dans sortedArrayRanks et voit qu'ils ont tous la même valeur dans sortedArray, et remplace à la place tous ces nombres dans un tableau de sortie avec la moyenne de ceux-ci (3,5 Ce qui me tracasse, c'est d'utiliser la récursivité ou une construction en boucle impérative, comme la boucle d'un tableau trié, et de voir si un élément est le même que celui qui l'a précédé, puis s'il coïncide, cochez celui qui le précède , etc. Comment cela peut-il être résolu? Merci!

+2

@Foredecker, pourquoi avez-vous ajouté cette balise sans aucun signe que l'auteur de la question était à la maison? – Dykam

Répondre

2

Cela ressemble beaucoup à F# How to Percentile Rank An Array of Doubles?. Voici une variante de ma réponse à cette question:

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 

Cela suppose que arr est trié et que les éléments de soutien arr comparaisons d'égalité.

+0

Ce code est vraiment beau. Aimer. Bon travail. –

0

Vous pouvez:

  • éléments zip et leurs rangs
  • groupe
  • ces paires par la valeur de l'élément
  • groupe moyen se classe
  • résultat sous forme
  • sous forme de tableau

et notez que algo comme script:

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|] 
Questions connexes