Je créais une fonction pour calculer la moyenne tronquée. Pour ce faire, j'ai supprimé le pourcentage de données le plus élevé et le plus bas, puis la moyenne est calculée comme d'habitude. Ce que j'ai jusqu'à présent, c'est:

def trimmed_mean(data, percent):
    from numpy import percentile

    if percent < 50:
        data_trimmed = [i for i in data
                        if i > percentile(data, percent)
                        and i < percentile(data, 100-percent)]
    else:
        data_trimmed = [i for i in data
                        if i < percentile(data, percent)
                        and i > percentile(data, 100-percent)]

    return sum(data_trimmed) / float(len(data_trimmed))

Mais j'obtiens le mauvais résultat. Donc, pour [37, 33, 33, 32, 29, 28, 28, 23, 22, 22, 22, 21, 21, 21, 20, 20, 19, 19, 18, 18, 18, 18, 16, 15, 14, 14, 14, 12, 12, 9, 6] de 10%, la moyenne devrait être 20.16 pendant que j'obtiens 20.0.

Existe-t-il un autre moyen de supprimer les données supérieures et inférieures en python? Ou y a-t-il autre chose que j'ai fait de mal?

3
Белякова Анастасия 7 mars 2016 à 18:00

4 réponses

Meilleure réponse

Vous pouvez jeter un œil à cette question connexe: Moyenne tronquée avec limite en pourcentage en Python?

En bref, pour la version scipy> 0.14.0, ce qui suit fait le travail

from scipy import stats
m = stats.trim_mean(X, percentage)

Si vous ne voulez pas avoir une dépendance sur une bibliothèque externe, vous pouvez bien sûr revenir à une approche comme indiqué dans la réponse Chip Grandits.

7
Community 23 mai 2017 à 11:52

Peut-être que cela fonctionnera:

data = [37, 33, 33, 32, 29, 28, 28, 23, 22, 22, 22, 21, 21, 21, 20, 20, 19, 19, 18, 18, 18, 18, 16, 15, 14, 14, 14, 12, 12, 9, 6]
percent = .1 # == 10%

def trimmed_mean(data, percent):
    # sort list
    data = sorted(data)
    # number of elements to remove from both ends of list
    g = int(percent * len(data))
    # remove elements
    data = data[g:-g]
    # cast sum to float to avoid implicit casting to int
    return float(sum(data)) / len(data)

print trimmed_mean(data, percent)

Production:

$ python trimmed_mean.py 
20.16
1
jDo 7 mars 2016 à 15:48

Je suggérerais d'abord de trier le tableau, puis de prendre une "tranche au milieu".

#some "fancy" numpy sort or even just plain old sorted()
#sorted_data = sorted(data) #uncomment to use plain python sorted 
n = len(sorted_data)
outliers = n*percent/100 #may want some rounding logic if n is small
trimmed_data = sorted_data[outliers: n-outliers]
2
Chip Grandits 7 mars 2016 à 15:16

Ici:

import numpy as np
def trimmed_mean(data, percent):
    data = np.array(sorted(data))
    trim = int(percent*data.size/100.0)
    return data[trim:-trim].mean()
1
jtitusj 7 mars 2016 à 15:35