Wie finden Sie den IQR in Numpy?

74

Gibt es eine eingebaute Numpy / Scipy-Funktion, um den Interquartilbereich zu ermitteln? Ich kann es ziemlich einfach selbst machen, aber es mean()gibt es im Grunde sum/len...

def IQR(dist):
    return np.percentile(dist, 75) - np.percentile(dist, 25)
Nick T.
quelle
Ich glaube nicht, dass es eine Funktion dafür gibt, Sie müssen die Perzentile so berechnen, wie Sie es getan haben.
BrenBarn
2
@BrenBarn. Es gibt jetzt ...
Mad Physicist

Antworten:

114

np.percentile nimmt mehrere Perzentilargumente an, und Sie sind etwas besser dran:

q75, q25 = np.percentile(x, [75 ,25])
iqr = q75 - q25

oder

iqr = np.subtract(*np.percentile(x, [75, 25]))

als zwei Anrufe zu tätigen percentile:

In [8]: x = np.random.rand(1e6)

In [9]: %timeit q75, q25 = np.percentile(x, [75 ,25]); iqr = q75 - q25
10 loops, best of 3: 24.2 ms per loop

In [10]: %timeit iqr = np.subtract(*np.percentile(x, [75, 25]))
10 loops, best of 3: 24.2 ms per loop

In [11]: %timeit iqr = np.percentile(x, 75) - np.percentile(x, 25)
10 loops, best of 3: 33.7 ms per loop
Jaime
quelle
Verwendung der Ufunc-Maschinerie , np.substract.reduce. IMHO, ein bisschen klarer als die * Magie.
Davidmh
1
@Jaime was ist der * Operator? Was macht es?
Sounak
2
Anschließend wird das Tupel entpackt, sodass der Funktion anstelle einer Sequenz mit zwei Elementen zwei einzelne Elemente übergeben werden.
Jaime
1
Das Subtrahieren von zwei Zahlen ist O (1), während das Finden von% iles O (n) erfordert. Daher ist es vollkommen in Ordnung, die beiden Dinge zu entpacken und sehr explizit hinzuzufügen.
Nick T
23

Es gibt jetzt eine iqrFunktion in scipy.stats. Es ist ab scipy 0.18.0 verfügbar. Meine ursprüngliche Absicht war es, es zu numpy hinzuzufügen, aber es wurde als zu domänenspezifisch angesehen.

Sie sind vielleicht besser dran, wenn Sie nur Jaimes Antwort verwenden, da der Scipy-Code nur eine überkomplizierte Version desselben ist.

Verrückter Physiker
quelle
4
Warum sollte IQR für numpy als zu domänenspezifisch angesehen werden?
Rob Rose
Weil es keine weit verbreitete Metrik ist. Fühlen Sie sich frei, die Mailingliste nach Details zu durchsuchen.
Verrückter Physiker
1

Ignorieren Sie dies, wenn Jaimes Antwort für Ihren Fall funktioniert. Wenn dies nicht der Fall ist, sollten Sie nach dieser Antwort Folgendes in Betracht ziehen , um die genauen Werte des 1. und 3. Quartils zu ermitteln:

samples = sorted([28, 12, 8, 27, 16, 31, 14, 13, 19, 1, 1, 22, 13])

def find_median(sorted_list):
    indices = []

    list_size = len(sorted_list)
    median = 0

    if list_size % 2 == 0:
        indices.append(int(list_size / 2) - 1)  # -1 because index starts from 0
        indices.append(int(list_size / 2))

        median = (sorted_list[indices[0]] + sorted_list[indices[1]]) / 2
        pass
    else:
        indices.append(int(list_size / 2))

        median = sorted_list[indices[0]]
        pass

    return median, indices
    pass

median, median_indices = find_median(samples)
Q1, Q1_indices = find_median(samples[:median_indices[0]])
Q2, Q2_indices = find_median(samples[median_indices[-1] + 1:])

IQR = Q3 - Q1

quartiles = [Q1, median, Q2]

Code aus der Antwort, auf die verwiesen wird.

Hamfry
quelle