← 返回编程题库
coding-quartile-pack-and-iqr-from-returns中等免费版2000ms未尝试

期间收益的四分位包与 IQR

Quartile Pack with IQR from Per-Period Returns

开始编码

量化研究台上的一个 tear-sheet「四分位包」报表辅助工具:把最近一批期间收益(每个期间一个浮点数)的 25/50/75 三个分位连同 IQR 一起,压成一行定长四列的记录发出去。下游解析这条记录是按位置(下标)取,不是按名字取,所以这个四元组的格式是契约死的。请实现 solution(returns: list[float]) -> list[float]:给定每期收益数组 returns[],返回 [q25, q50, q75, iqr],三个分位用线性插值取,iqr = q75 - q25

算法分两步走。(1) 把 returns 升序排序得到 sorted[0..N-1]。(2) 对每个 p 取 {25.0, 50.0, 75.0},计算 h = (N - 1) * p / 100;设 i = floor(h)frac = h - i;如果 i == N - 1 就取 q = sorted[N - 1],否则 q = sorted[i] + frac * (sorted[i + 1] - sorted[i])。最后把 q75 - q25 写到第四位。整体复杂度由那一次排序决定,是 O(N log N);三次分位读取每次都是 O(1)。

举一个具体例子:solution([-3.0, -1.0, 2.0, 4.0]) 排序后是 [-3.0, -1.0, 2.0, 4.0](已经升序)。p = 25 时 h = (4 - 1) * 0.25 = 0.75,i = 0,frac = 0.75,q25 = -3.0 + 0.75 * (-1.0 - -3.0) = -1.5;p = 50 时 h = 1.5,q50 = -1.0 + 0.5 * (2.0 - -1.0) = 0.5(即中间两个样本的平均);p = 75 时 h = 2.25,q75 = 2.0 + 0.25 * (4.0 - 2.0) = 2.5。IQR = 2.5 - (-1.5) = 4.0,答案是 [-1.5, 0.5, 2.5, 4.0]

三处坑提一下。第一,分母:写成 N * p / 100 而不是 (N - 1) * p / 100,p = 100 时 h = N,下标越界——这正是 numpy 把 "linear" 单独命名、与 "lower"/"higher"/"nearest" 区分的根源。第二,空输入哨兵:N = 0 必须返回 [NaN, NaN, NaN, NaN](四个 NaN)——空数组上四个分位都未定义,但下游报表那一行还是要按四列定长发出去,所以我们用 NaN 编码「未定义」而不是抛异常。第三,q25 == q75 时不要省略 IQR:所有收益相等时 IQR = 0.0,这一包是 [v, v, v, 0.0],不是三元素。

约束条件

  • 0 <= N <= 5000,N = len(returns)。N = 0 是合法输入——返回 NaN 四元组哨兵,而不是抛出异常。
  • 每个收益是带符号的有限浮点数,绝对值不超过 1e6,可以是负数、可以重复、不保证有序。
  • 分位数约定:线性插值,`h = (N - 1) * p / 100`,p 取 {25, 50, 75},匹配 `numpy.percentile(..., method="linear")` 的语义。
  • 输出是四元素列表 `[q25, q50, q75, q75 - q25]`。浮点比较绝对容差为 1e-9。
  • 四分位包的格式是契约死的:不要重排四个位置的顺序,IQR 即使是 0 也必须保留这一位。

样例

Case 1 · typical 12-period returns, mixed sign

输入: [[-0.025,0.012,0.005,-0.008,0.018,-0.011,0.03,-0.004,0.015,0.022,-0.018,0.008]]

期望: [-0.00875,0.006500000000000001,0.01575,0.0245]

12 个收益升序为 [-0.025, -0.018, -0.011, -0.008, -0.004, 0.005, 0.008, 0.012, 0.015, 0.018, 0.022, 0.030]。q25 在 h=(12-1)*0.25=2.75,落在 sorted[2]=-0.011 与 sorted[3]=-0.008 之间,frac=0.75,得 -0.011 + 0.75*(-0.008 - -0.011) = -0.00875;q50 在 h=5.5,sorted[5]=0.005 与 sorted[6]=0.008 之间,得 0.0065;q75 在 h=8.25,sorted[8]=0.015 与 sorted[9]=0.018 之间,frac=0.25,得 0.01575;iqr = q75 - q25 = 0.0245。

Case 2 · even-N=4 quartile pack — straddles middle

输入: [[-3,-1,2,4]]

期望: [-1.5,0.5,2.5,4]

n=4 升序就是 [-3, -1, 2, 4]。q25 在 h=(4-1)*0.25=0.75,sorted[0]=-3 与 sorted[1]=-1 之间,frac=0.75,得 -3 + 0.75*(-1 - -3) = -1.5;q50 在 h=1.5,sorted[1] 与 sorted[2] 之间,frac=0.5,得 -1 + 0.5*(2 - -1) = 0.5;q75 在 h=2.25,sorted[2]=2 与 sorted[3]=4 之间,frac=0.25,得 2.5;iqr = 2.5 - (-1.5) = 4.0。

最近提交

还没有提交记录。

编码区

实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。

加载编辑器...
计时0:00

默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。

Case 1 · typical 12-period returns, mixed sign

输入: [[-0.025,0.012,0.005,-0.008,0.018,-0.011,0.03,-0.004,0.015,0.022,-0.018,0.008]]

期望: [-0.00875,0.006500000000000001,0.01575,0.0245]

12 个收益升序为 [-0.025, -0.018, -0.011, -0.008, -0.004, 0.005, 0.008, 0.012, 0.015, 0.018, 0.022, 0.030]。q25 在 h=(12-1)*0.25=2.75,落在 sorted[2]=-0.011 与 sorted[3]=-0.008 之间,frac=0.75,得 -0.011 + 0.75*(-0.008 - -0.011) = -0.00875;q50 在 h=5.5,sorted[5]=0.005 与 sorted[6]=0.008 之间,得 0.0065;q75 在 h=8.25,sorted[8]=0.015 与 sorted[9]=0.018 之间,frac=0.25,得 0.01575;iqr = q75 - q25 = 0.0245。

Case 2 · even-N=4 quartile pack — straddles middle

输入: [[-3,-1,2,4]]

期望: [-1.5,0.5,2.5,4]

n=4 升序就是 [-3, -1, 2, 4]。q25 在 h=(4-1)*0.25=0.75,sorted[0]=-3 与 sorted[1]=-1 之间,frac=0.75,得 -3 + 0.75*(-1 - -3) = -1.5;q50 在 h=1.5,sorted[1] 与 sorted[2] 之间,frac=0.5,得 -1 + 0.5*(2 - -1) = 0.5;q75 在 h=2.25,sorted[2]=2 与 sorted[3]=4 之间,frac=0.25,得 2.5;iqr = 2.5 - (-1.5) = 4.0。