查询列表中百分位数的有效方法
Efficient method to query percentile in a list
我遇到过几次从列表中收集百分位数的要求:
- 某个数字在哪个百分位数内?
- 列表中的第 n 个百分位数是多少?
我写了这些方法来解决这个问题:
/for 1:
percentileWithinThreshold:{[threshold;list] (100 * count where list <= threshold) % count list};
/for 2:
thresholdForPercentile:{[percentile;list] (asc list)[-1 + "j"$((percentile % 100) * count list)]};
它们适用于两种用例,但我认为这是一个太常见的用例,所以 Q 可能已经提供了一些开箱即用的东西来做同样的事情。知道是否已经存在其他东西吗?
'100 xrank' 生成百分位数。
q) 100 xrank 1 2 3 4
q) 0 25 50 75
第二个需求的解决方案:
q) f:{ y (100 xrank y:asc y) bin x}
另请注意,您的第二个函数结果不会始终与 xrank 相同。原因是 'xrank' 使用 floor 作为分数索引输出,这是计算百分位数的正常情况,您的函数将值四舍五入并减去 -1,这确保输出始终小于输入百分位数。例如:
q) thresholdForPercentile[63;til 21] / output 12
q) f[63;til 21] / output 13
第一个要求,没有内置函数。但是,如果您对输入列表进行排序,则可以改进您的功能,因为在这种情况下,您可以使用 'bin' 函数,它在大列表上运行得更快。
q) percentileWithinThreshold:{[threshold;list] (100 * 1+list bin threshold) % count list};
请记住,如果一个参数是 float 类型而另一个是整数,'bin' 将抛出类型错误。因此,请确保在函数中正确地转换它们。
qtln:{[x;y;z]cf:(0 1;1%2 2;0 0;1 1;1%3 3;3%8 8) z-4;n:count y:asc y;?[hf<1;first y;last y]^y[hf-1]+(h-hf)*y[hf]-y -1+hf:floor h:cf[0]+x*n+1f-sum cf}
qtl:qtln[;;8];
我遇到过几次从列表中收集百分位数的要求:
- 某个数字在哪个百分位数内?
- 列表中的第 n 个百分位数是多少?
我写了这些方法来解决这个问题:
/for 1:
percentileWithinThreshold:{[threshold;list] (100 * count where list <= threshold) % count list};
/for 2:
thresholdForPercentile:{[percentile;list] (asc list)[-1 + "j"$((percentile % 100) * count list)]};
它们适用于两种用例,但我认为这是一个太常见的用例,所以 Q 可能已经提供了一些开箱即用的东西来做同样的事情。知道是否已经存在其他东西吗?
'100 xrank' 生成百分位数。
q) 100 xrank 1 2 3 4
q) 0 25 50 75
第二个需求的解决方案:
q) f:{ y (100 xrank y:asc y) bin x}
另请注意,您的第二个函数结果不会始终与 xrank 相同。原因是 'xrank' 使用 floor 作为分数索引输出,这是计算百分位数的正常情况,您的函数将值四舍五入并减去 -1,这确保输出始终小于输入百分位数。例如:
q) thresholdForPercentile[63;til 21] / output 12
q) f[63;til 21] / output 13
第一个要求,没有内置函数。但是,如果您对输入列表进行排序,则可以改进您的功能,因为在这种情况下,您可以使用 'bin' 函数,它在大列表上运行得更快。
q) percentileWithinThreshold:{[threshold;list] (100 * 1+list bin threshold) % count list};
请记住,如果一个参数是 float 类型而另一个是整数,'bin' 将抛出类型错误。因此,请确保在函数中正确地转换它们。
qtln:{[x;y;z]cf:(0 1;1%2 2;0 0;1 1;1%3 3;3%8 8) z-4;n:count y:asc y;?[hf<1;first y;last y]^y[hf-1]+(h-hf)*y[hf]-y -1+hf:floor h:cf[0]+x*n+1f-sum cf}
qtl:qtln[;;8];