クォンタイル

シーケンスを渡してクォンタイルを計算する。

# ankka.py
import math

class Quantile:
    def __init__(self, seq):
        self.seq = list(seq)
        self.seq.sort()
        self.last_idx = len(seq) - 1

    def q(self, v):
        idx = v * self.last_idx
        idx_l = math.floor(idx)
        idx_u = math.ceil(idx)
        print([idx_l, idx, idx_u])
        if idx_l == idx_u:
            return self.seq[idx_l]
        else:
            return (idx_u - idx) * self.seq[idx_l] + (idx - idx_l) * self.seq[idx_u]

平均値の回りに値が散らばっている他に極端な値がちょっと含まれているようなシーケンスで試す。

# python3
>>> import random
>>> import itertools
>>> seq = list(itertools.chain((random.randint(0,10) for i in range(2)),(random.randint(100,120) for i in range(20)))
>>> seq
[2, 1, 101, 114, 116, 103, 106, 114, 114, 102, 105, 112, 119, 115, 107, 108, 104, 111, 115, 102, 108, 109]

で、中央値 (0.5 クォンタイル) と 0.25 クォンタイルを計算してみる。

>>> q = ankka.Quantile(seq)
>>> q.q(0.5)
108.0
>>> q.q(0.25)
103.25

ちなみに平均は

>>> sum(seq)/len(seq)
99.45454545454545

そんな感じで。