F#如何对双打数组进行百分等级? [英] F# How to Percentile Rank An Array of Doubles?

查看:63
本文介绍了F#如何对双打数组进行百分等级?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在F#中采用数字数组,并对所有元素进行排名,以使关系获得相同的排名.基本上,我正在尝试复制下面在C#中拥有的算法,但仅用于双精度数组.帮助?

I am trying to take a numeric array in F#, and rank all the elements so that ties get the same rank. Basically I'm trying to replicate the algorithm I have below in C#, but just for an array of doubles. Help?

rankMatchNum = 0; rankMatchSum = 0; previousScore = -999999999;

rankMatchNum = 0; rankMatchSum = 0; previousScore = -999999999;

        for (int i = 0; i < factorStocks.Count; i++)
        {
            //The 1st time through it won't ever match the previous score...
            if (factorStocks[i].factors[factorName + "_R"] == previousScore)
            {
                rankMatchNum = rankMatchNum + 1;     //The count of matching ranks
                rankMatchSum = rankMatchSum + i + 1; //The rank itself...
                for (int j = 0; j <= rankMatchNum; j++)
                {
                    factorStocks[i - j].factors[factorName + "_WR"] = rankMatchSum / (rankMatchNum + 1);
                }
            }
            else
            {
                rankMatchNum = 0;
                rankMatchSum = i + 1;
                previousScore = factorStocks[i].factors[factorName + "_R"];
                factorStocks[i].factors[factorName + "_WR"] = i + 1;
            }
        }

推荐答案

尽管这不是您代码的直接翻译,但我将按照以下方法进行操作.我已经以一种功能性的方式完成了工作,将结果从一种转换传递到另一种.

Here's how I would do it, although this isn't a direct translation of your code. I've done things in a functional style, piping results from one transformation to another.

let rank seq =
  seq
  |> Seq.countBy (fun x -> x)     // count repeated numbers
  |> Seq.sortBy (fun (k,v) -> k)  // order by key
  |> Seq.fold (fun (r,l) (_,n) -> // accumulate the number of items seen and the list of grouped average ranks
      let r'' = r + n             // get the rank after this group is processed
      let avg = List.averageBy float [r+1 .. r''] // average ranks for this group
      r'', ([for _ in 1 .. n -> avg]) :: l)       // add a list with avg repeated
      (0,[])                          // seed the fold with rank 0 and an empty list 
      |> snd                          // get the final list component, ignoring the component storing the final rank
      |> List.rev                     // reverse the list
      |> List.collect (fun l -> l)    // merge individual lists into final list

或者复制Mehrdad的样式:

Or to copy Mehrdad's style:

let rank arr =
  let lt item = arr |> Seq.filter (fun x -> x < item) |> Seq.length
  let lte item = arr |> Seq.filter (fun x -> x <= item) |> Seq.length
  let avgR item = [(lt item) + 1 .. (lte item)] |> List.averageBy float
  Seq.map avgR arr

这篇关于F#如何对双打数组进行百分等级?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆