2010-08-20 5 views
4

Y at-il une bibliothèque intégrée que je peux utiliser pour calculer la médiane en Java?Calculs statistiques

Je travaillais avec apache.commons.math pour d'autres fonctions statistiques mais la médiane était introuvable.

Merci,

Répondre

7

Quelle version d'Apache Commmons Math utilisez-vous? Il y a une classe médiane au moins à partir de la 2.1 (ancienne version je ne suis pas sûr). Vous pouvez l'utiliser comme:

Median median = new Median(); 
median.evaluate(values); 
+0

fonctionne! super merci :) J'utilisais 2.0: P – JJunior

+3

Quel genre de conception d'API surdimensionné ridicule est-ce? À mon humble avis, il n'y a aucune excuse pour quelque chose d'aussi simple que de caluler une médiane nécessitant l'instanciation d'un objet et de prendre plus d'une ligne de code. – dsimcha

+1

double médiane = new Médiane(). Evaluate (valeurs); De rien. – Matunos

9

Mettez tous les numéros dans une liste, trier la liste, et prendre la valeur moyenne (ou la moyenne des deux valeurs moyennes pour même taille). Aucun calcul nécessaire

+0

ok donc le tri et prenant la valeur moyenne qui est: SortedList [SortedList .lenght/2] devrait me donner la bonne médiane droite? – JJunior

+0

Vous devez vérifier si sortedList.length% 2 == 0 et si oui, prendre la moyenne de sortedList.length/2 & (sortedList.length/2) + 1 - c'est exactement le genre de chose que vous devez tester unitairement –

+0

médiane statistique n'est rien de plus que la valeur moyenne, alors oui cela devrait être bien. Quand il y a un nombre pair de valeurs, cependant, vous ne pouvez pas simplement prendre le milieu puisqu'il n'y a pas de milieu. Au lieu de cela, vous devriez prendre la moyenne des deux valeurs les plus proches du milieu. Dans une liste de taille 4, faites la moyenne des deuxième et troisième valeurs. Code sage, ce serait '(liste [liste.length/2] + liste [(liste.length/2) +1])/2' –

2

Récupère les valeurs dans un objet List. Supposons que les valeurs soient des entiers et que la liste soit appelée "valeurs". Puis

List<Integer> values; 
... populate values ... 
Collections.sort(values); 
int median; 
int midpoint=values.size()/2; 
if (values.size()%2==1) 
    median=values.get(midpoint+1).intValue(); 
else 
    median=(values.get(midpoint).intValue()+values.get(midpoint+1).intValue())/2; 

Si le nombre de valeurs est grande, comme dans les centaines ou plus, de jouer avec le mod-2 peut être techniquement correcte mais superflue.

Peut-être y at-il un moyen plus efficace de le faire - le tri est plutôt lent sur une grande liste - mais cela fonctionnerait.

Oh, et vous devriez vraiment vérifier une liste avec zéro entrées. Peut-être qu'il me manque d'autres conditions aux limites.

+0

Votre formule est correcte, mais la manipulation de la liste de tableaux est incorrecte. Votre réponse entraîne une mauvaise sortie. ArrayList # get L'index de méthode commence à partir de '0', donc il échoue lorsque la liste a 2 éléments,' ArrayIndexOutOfBoundsException' se produit. Puis-je corriger le code? –

+0

Oh, vous avez raison. Maladroit de moi. La dernière ligne devrait prendre le point milieu et le point milieu MINUS 1, pas PLUS 1. Je pense que c'est correct à part ça. N'hésitez pas à vous moquer si vous voyez une autre erreur. :-) – Jay

1

De la "too-much-temps sur mes mains" département: voici une petite classe MedianGenerator:

/** 
* Methods to calculate the median value of a supplied {@link List}. 
*/ 
public final class MedianGenerator{ 

    private MedianGenerator(){ 
    } 

    /** 
    * Calculate the median of a supplied list. 
    * <ol> 
    * <li>A copy will be generated</li> 
    * <li>this copy will be sorted with the supplied comparator</li> 
    * <li>the median will be calculated, using the supplied averageCalculator 
    * for collections with an even number of items</li> 
    * </ol> 
    * 
    * @param data 
    * @param comparator 
    * @param averageCalculator 
    * @return the median 
    */ 
    public static <T> T calculateMedian(final List<T> data, 
     final Comparator<? super T> comparator, 
     final AverageCalculator<T> averageCalculator){ 
     final List<T> copy = new ArrayList<T>(data); 
     Collections.sort(copy, comparator); 
     return doCalculateMedian(data, averageCalculator); 

    } 

    /** 
    * Calculate the median of a supplied list. 
    * <ol> 
    * <li>A copy will be generated</li> 
    * <li>this copy will be sorted with the supplied comparator</li> 
    * <li>the median will be calculated, using the {@link #ALWAYS_FIRST} {@link AverageCalculator} 
    * for collections with an even number of items</li> 
    * </ol> 
    * 
    * @param data 
    * @param comparator 
    * @return the median 
    */ 
    @SuppressWarnings("unchecked") 
    public static <T> T calculateMedian(final List<T> data, 
     final Comparator<? super T> comparator){ 
     return calculateMedian(data, comparator, (AverageCalculator<T>) ALWAYS_FIRST); 
    } 

    /** 
    * Calculate the median of a supplied list. 
    * <ol> 
    * <li>A copy will be generated</li> 
    * <li>this copy will be sorted using natural ordering</li> 
    * <li>the median will be calculated, using the {@link #ALWAYS_FIRST} {@link AverageCalculator} 
    * for collections with an even number of items</li> 
    * </ol> 
    * 
    * @param data 
    * @return the median 
    */ 
    @SuppressWarnings("unchecked") 
    public static <T extends Comparable<? super T>> T calculateMedian(final List<T> data){ 
     return calculateMedian(data, (AverageCalculator<T>) ALWAYS_FIRST); 
    } 

    /** 
    * Calculate the median of a supplied list. 
    * <ol> 
    * <li>A copy will be generated</li> 
    * <li>this copy will be sorted using natural ordering</li> 
    * <li>the median will be calculated, using the supplied averageCalculator 
    * for collections with an even number of items</li> 
    * </ol> 
    * 
    * @param data 
    * @param averageCalculator 
    * @return the median 
    */ 
    public static <T extends Comparable<? super T>> T calculateMedian(final List<T> data, 
     final AverageCalculator<T> averageCalculator){ 
     final List<T> copy = new ArrayList<T>(data); 
     Collections.sort(copy); 
     return doCalculateMedian(copy, averageCalculator); 
    } 

    private static <T> T doCalculateMedian(final List<T> sortedData, 
     final AverageCalculator<T> averageCalculator){ 
     T result; 
     if(sortedData.isEmpty()){ 
      result = null; 
     } else{ 
      final int size = sortedData.size(); 
      if(size % 2 == 0){ 
       result = 
        averageCalculator.getAverage(sortedData.get(size/2 - 1), 
         sortedData.get(size/2)); 
      } else{ 
       result = sortedData.get(size/2 - 1); 
      } 

     } 
     return result; 
    } 

    /** 
    * Generic accessor method for {@link #ALWAYS_FIRST}. 
    */ 
    @SuppressWarnings("unchecked") 
    public static <T> AverageCalculator<T> alwaysFirst(){ 
     return ALWAYS_FIRST; 
    } 

    /** 
    * {@link AverageCalculator} implementation that always returns the lower 
    * bound unchanged. 
    */ 
    @SuppressWarnings("rawtypes") 
    public static final AverageCalculator ALWAYS_FIRST = 
     new AverageCalculator(){ 

      @Override 
      public Object getAverage(final Object first, final Object second){ 
       return first; 
      } 

     }; 

    /** 
    * When there is an even number of items, this interface is used to generate 
    * the average between the two middle items. 
    */ 
    public static interface AverageCalculator<E> { 

     E getAverage(E first, E second); 
    } 

}