F# - 基于百分比比较用标签替换浮点数

mat*_*kus 2 arrays f# dictionary percentile

我需要根据与prcntl中百分位数的比较将tmp中的值映射到tmpRplcd中的标签,但是Array.map2行会因为数组的长度不同而失败.

module SOQN = 
   open System
   open MathNet.Numerics.Statistics
   let tmp = [| 13.0; 17.0; 23.0; 11.0; 11.0; 13.0; 31.0; 
                19.0; 47.0; 29.0; 29.0; 19.0; 43.0; 37.0 |]
   let tmpPrcntls = 
      tmp
      |> Array.sort
   let lbls = [| "p0"; "p1"; "p2"; "p3"; "p4";"p5" |]
   let prcntls = [| Statistics.Percentile(tmpPrcntls,0)   // 11.0
                    Statistics.Percentile(tmpPrcntls,20)  // 13.0
                    Statistics.Percentile(tmpPrcntls,40)  // 19.0
                    Statistics.Percentile(tmpPrcntls,60)  // 28.6
                    Statistics.Percentile(tmpPrcntls,80)  // 35.8
                    Statistics.Percentile(tmpPrcntls,100) // 47.0
                 |]
   let lkpTbl = Map(Array.zip prcntls lbls)
   let tmpRplcd:string[] = 
      tmp
      |> Array.map2 (fun x y -> if x <= y then lkpTbl.[y] else "") prcntls
   let main = 
      printfn ""
      printfn "Percentile Test"
      printfn ""
      printfn "tmpPrcntls: %A" tmpPrcntls
      printfn "prcntls:%A" prcntls
      printfn "tmpRplcd:%A" tmpRplcd
      0
   [<EntryPoint>]
   main
   |> ignore

 // Expected Result:
 // tmpRplcd = [| "p1"; "p2"; "p3"; "p0"; "p0"; "p1"; "p4"; 
 //               "p2"; "p5"; "p4"; "p4"; "p2"; "p5"; "p5" |]   
Run Code Online (Sandbox Code Playgroud)

我哪里错了?

Tom*_*cek 5

我认为你的使用map2是错误的 - map2函数拉链两个数组,然后将给定的函数应用于压缩数组.

根据你的问题,我的猜测是你真的想做别的事情.对于每个输入,您希望迭代所有百分位数并找到第一个百分位数,使得该值比百分位数更大(或更小?).为此,您需要替换map2为以下内容:

let tmpRplcd:string[] = 
  tmp 
  |> Array.map (fun y -> 
    prcntls |> Array.tryPick (fun x ->
      if x <= y then Some(lkpTbl.[x]) else None))
  |> Array.map (fun v -> defaultArg v "")
Run Code Online (Sandbox Code Playgroud)

我没有合适的版本试试这个,但我认为这应该做你需要的(我只是不确定你是否需要x <= y或反过来!)