2010-08-20 110 views
4

是否有任何內置的庫,我可以用它來計算中值在Java?統計計算

我正在爲其他統計函數使用apache.commons.math,但中位數無處可查。

謝謝

回答

7

您使用的是哪個版本的Apache Commmons Math?至少在2.1以上的時候有一箇中級班(我不太確定老班)。您可以將其用作:

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

的作品!非常感謝:)我使用2.0:P – JJunior 2010-08-20 14:21:05

+3

什麼樣的一個荒謬的過度工程API設計是這樣的?恕我直言,沒有任何理由像調整中位數要求實例化一個對象並採取多行代碼一樣簡單。 – dsimcha 2010-08-20 20:29:13

+1

double median = new Median()。evaluate(values); 不客氣。 – Matunos 2013-10-11 21:26:43

9

把所有的數字到一個列表,列表進行排序,取中間值(或平均兩個中間值的大小均勻)。無需計算

+0

確定,所以選它,取中間值是: 排序列表[排序列表.lenght/2] 應該給我正確的中位數嗎? – JJunior 2010-08-20 13:52:07

+0

你需要檢查sortedList.length%2 == 0,如果是這樣取平均值sortedList.length/2&(sortedList.length/2)+ 1 - 這正是你應該單元測試的東西 – 2010-08-20 13:59:31

+0

統計中位數不過是中間值,所以是的,應該沒問題。但是,如果有偶數個數值,則不能只取中間值,因爲沒有中間值。相反,你應該把這兩個值的平均值最接近中間值。在大小爲4的列表中,平均第二個和第三個值。代碼明智的,它會是'(list [list.length/2] + list [(list.length/2)+1])/ 2' – 2010-08-20 14:02:13

2

將值獲取到List對象中。假設這些值是整數,並且該列表被稱爲「值」。然後

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; 

如果值的數量很大,比如在數百或更多,那麼與mod-2混合可能在技術上是正確的但是多餘的。

也許有一種更有效的方法來做到這一點 - 排序是很大的列表上很慢 - 但這是行得通的。

哦,你真的應該檢查一個零條目列表。也許我錯過了其他邊界條件。

+0

你的公式是正確的,但只是數組列表操作是錯誤的。您的答案結果錯誤輸出。 ArrayList#get方法索引從「0」開始,所以當列表包含2個元素時會失敗,出現「ArrayIndexOutOfBoundsException」。我可以修復代碼嗎? – 2013-11-08 10:38:15

+0

哦,你說得對。笨拙的我。最後一行應該是中點和中點減號1,而不是加1。除此之外,我認爲這是正確的。如果你看到另一個錯誤,請隨意嘲笑。 :-) – Jay 2013-11-08 18:18:37

1

從「太多的時間啓動,我的雙手」部門:這裏是一個小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); 
    } 

}