统计计算

时间:2010-08-20 13:42:35

标签: java statistics

我是否有可用于计算java中位数的内置库?

我正在使用apache.commons.math处理其他统计函数,但中位数无处可寻。

谢谢,

5 个答案:

答案 0 :(得分:9)

将所有数字放入列表,对列表进行排序,并取中间值(或偶数大小的两个中间值的平均值)。无需计算

答案 1 :(得分:7)

您使用的是哪个版本的Apache Commons Math?至少在2.1以后有一个中位数类(旧版本我不确定)。您可以将其用作:

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

答案 2 :(得分:2)

尝试Median对象。

答案 3 :(得分: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在技术上可能是正确的但是多余的。

也许有一种更有效的方法 - 在大型列表中排序相当慢 - 但这可行。

哦,你真的应该检查零条目的列表。也许我错过了其他边界条件。

答案 4 :(得分: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);
    }

}