F#技术问题:基于百分位比较将浮点数替换为标签
问题分析与修正
嘿,你遇到的问题根源在于**Array.map2的使用场景不对**——这个函数要求传入的两个数组长度必须完全一致,它会把两个数组对应位置的元素配对后执行处理逻辑。但你的tmp数组有14个元素,prcntls只有6个,长度不匹配,所以执行时会直接抛出错误。
而你真正想要的逻辑是:对tmp里的每一个数值,找到它落在哪个百分位区间内,然后映射到对应的lbls标签。我们可以换一种方式实现这个逻辑:
修正后的代码
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 |] // 核心修正:对每个tmp元素,找到第一个满足x<=百分位值的标签 let tmpRplcd:string[] = tmp |> Array.map (fun x -> Array.zip prcntls lbls |> Array.pick (fun (percentile, label) -> if x <= percentile then Some label else None ) ) let main = printfn "" printfn "Percentile Test" printfn "" printfn "tmpPrcntls: %A" tmpPrcntls printfn "prcntls:%A" prcntls printfn "tmpRplcd:%A" tmpRplcd 0 [<EntryPoint>] main |> ignore
逻辑说明
- 用
Array.zip prcntls lbls把百分位数值和对应的标签打包成元组数组,得到类似[(11.0, "p0"); (13.0, "p1"); ...]的结构。 - 对
tmp里的每个数值x,用Array.pick遍历这个元组数组:Array.pick会返回第一个满足条件(x <= percentile)的标签(通过Some label返回);- 不满足条件的项返回
None,函数会继续遍历下一个。
- 这样就能准确把每个数值映射到对应的百分位标签,完全符合你给出的预期结果。
内容的提问来源于stack exchange,提问作者matekus
相关产品推荐
相关产品推荐

