2010-08-20 114 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); 
    } 

}