Arrays F-用基于百分位比较的标签替换浮动
我需要将tmp中的值映射到tmpRplcd中的标签,基于与prcntls中的百分位数的比较,但是Array.map2行失败,因为数组的长度不同Arrays F-用基于百分位比较的标签替换浮动,arrays,dictionary,f#,percentile,Arrays,Dictionary,F#,Percentile,我需要将tmp中的值映射到tmpRplcd中的标签,基于与prcntls中的百分位数的比较,但是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; 3
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" |]
哪里出错了?我认为您使用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 "")
我没有合适的版本来尝试这个,但我认为这应该满足您的需要我只是不确定您是否需要x我认为您使用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 "")
我没有合适的版本来尝试这个,但是我认为这个应该可以满足你的需要,我只是不确定你是否需要x这里有一个方法,你可以用你的F程序来做 我从中提出了百分比计算的实现,如下面的统计模块所示
namespace FSharpBasics
module Statistics =
let percentile p (array: float[]) =
let threshold = (float p / 100.0) * float (array |> Array.length)
let thresholdCeiling = int (System.Math.Ceiling threshold)
let thresholdInteger = int (threshold)
array
|> Array.sort
|> Array.skip (thresholdCeiling - 1)
|> Array.truncate (if thresholdInteger = thresholdCeiling then 2 else 1)
|> Array.average
module PercentileTest =
open System
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 lbls =
[| for n in 0..20..100 -> "p" + string (n / 20) |]
let prcntls =
[| for n in 0..20..100 -> Statistics.percentile n tmp |]
let tmpPrcntls =
tmp |> Array.sort
let lkpTbl =
Array.zip prcntls lbls
let tmpRplcd : string[] =
tmp
|> Array.map (fun x ->
lkpTbl
|> Array.filter (fun (prcntl, lbl) -> prcntl <= x)
|> Array.last
|> snd)
[<EntryPoint>]
let main argv =
printfn ""
printfn "Percentile Test"
printfn ""
printfn "tmp: %A" tmp
printfn "tmpPrcntls: %A" tmpPrcntls
printfn "prcntls: %A" prcntls
printfn "tmpRplcd: %A" tmpRplcd
System.Console.ReadKey() |> ignore
0 // return an integer exit code
(*---- output ----
Percentile Test
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|]
tmpPrcntls: [|11.0; 11.0; 13.0; 13.0; 17.0; 19.0; 19.0; 23.0; 29.0; 29.0; 31.0; 37.0; 43.0;
47.0|]
prcntls: [|11.0; 13.0; 19.0; 29.0; 37.0; 47.0|]
tmpRplcd: [|"p1"; "p1"; "p2"; "p0"; "p0"; "p1"; "p3"; "p2"; "p5"; "p3"; "p3"; "p2"; "p4";
"p4"|]
---- ----*)
下面是一个你打算用F程序做什么的方法 我从中提出了百分比计算的实现,如下面的统计模块所示
namespace FSharpBasics
module Statistics =
let percentile p (array: float[]) =
let threshold = (float p / 100.0) * float (array |> Array.length)
let thresholdCeiling = int (System.Math.Ceiling threshold)
let thresholdInteger = int (threshold)
array
|> Array.sort
|> Array.skip (thresholdCeiling - 1)
|> Array.truncate (if thresholdInteger = thresholdCeiling then 2 else 1)
|> Array.average
module PercentileTest =
open System
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 lbls =
[| for n in 0..20..100 -> "p" + string (n / 20) |]
let prcntls =
[| for n in 0..20..100 -> Statistics.percentile n tmp |]
let tmpPrcntls =
tmp |> Array.sort
let lkpTbl =
Array.zip prcntls lbls
let tmpRplcd : string[] =
tmp
|> Array.map (fun x ->
lkpTbl
|> Array.filter (fun (prcntl, lbl) -> prcntl <= x)
|> Array.last
|> snd)
[<EntryPoint>]
let main argv =
printfn ""
printfn "Percentile Test"
printfn ""
printfn "tmp: %A" tmp
printfn "tmpPrcntls: %A" tmpPrcntls
printfn "prcntls: %A" prcntls
printfn "tmpRplcd: %A" tmpRplcd
System.Console.ReadKey() |> ignore
0 // return an integer exit code
(*---- output ----
Percentile Test
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|]
tmpPrcntls: [|11.0; 11.0; 13.0; 13.0; 17.0; 19.0; 19.0; 23.0; 29.0; 29.0; 31.0; 37.0; 43.0;
47.0|]
prcntls: [|11.0; 13.0; 19.0; 29.0; 37.0; 47.0|]
tmpRplcd: [|"p1"; "p1"; "p2"; "p0"; "p0"; "p1"; "p3"; "p2"; "p5"; "p3"; "p3"; "p2"; "p4";
"p4"|]
---- ----*)
非常好,托马斯佩特里切克。x>=y是正确的选项。再次感谢您的清晰解释和您的专业知识。非常好@TomasPetricek。x>=y是正确的选项。再次感谢您的清晰解释和您的专业知识。@MarceloUchimura。谢谢你的详细答复。不幸的是,我得到的预期输出与您的程序生成的实际输出不匹配://expected Result://tmpRplcd=[|p1;p2;p3;p0;p0;p1;p4;p2;p5;p4;p2;p5 |]//实际结果://tmpRplcd:[| p1;p1;p2;p0;p0;p1;p3;p2;p5;p3;p3;p2;p4;p4 |]@matekus:可能不匹配是由于使用了不同的统计数据包。我担心tmp中37.0的最后一个值不能在p5百分位数中,因为它小于47.0。@MarceloUchimura,37.0应该转换为p5。@matekus,我担心tmp中唯一属于p5的值是47.0,这是t中所有值中最大的值他在列表中。@MarceloUchimura。感谢您的详细回复。不幸的是,我发现您的程序生成的预期输出与实际输出不匹配://预期结果://tmpRplcd=[|p1;p2;p3;p0;p0;p1;p4;p2;p5;p4;p4;p2;p5;p5 |]//实际结果://tmpRplcd:[|p1;p1;p2;p0;p0;p1;p3;p2;p5;p3;p3;p2;p4;p4 |]@matekus:可能不匹配是由于使用了不同的统计数据包。我担心tmp中37.0的最后一个值不能在p5百分位数中,因为它小于47.0。@MarceloUchimura,37.0应该转换为p5。@matekus,我担心tmp中唯一属于p5的值是47.0,这是t中所有值中最大的值他列出了清单。