2010-11-16 6 views

Antwort

61

Ja, es scheint dritte Bibliotheken zu geben (keine in Java Math). Zwei, die gekommen sind, nach oben sind:

http://opsresearch.com/app/

http://www.iro.umontreal.ca/~simardr/ssj/indexe.html

aber es eigentlich nicht so schwierig ist, Ihre eigenen Methoden zu schreiben, Mittelwert, Median, Modus und Bereich zu berechnen.

MEAN

public static double mean(double[] m) { 
    double sum = 0; 
    for (int i = 0; i < m.length; i++) { 
     sum += m[i]; 
    } 
    return sum/m.length; 
} 

MEDIAN

// the array double[] m MUST BE SORTED 
public static double median(double[] m) { 
    int middle = m.length/2; 
    if (m.length%2 == 1) { 
     return m[middle]; 
    } else { 
     return (m[middle-1] + m[middle])/2.0; 
    } 
} 

MODE

public static int mode(int a[]) { 
    int maxValue, maxCount; 

    for (int i = 0; i < a.length; ++i) { 
     int count = 0; 
     for (int j = 0; j < a.length; ++j) { 
      if (a[j] == a[i]) ++count; 
     } 
     if (count > maxCount) { 
      maxCount = count; 
      maxValue = a[i]; 
     } 
    } 

    return maxValue; 
} 

UPDATE

Wie von Neelesh Salpe darauf hingewiesen wurde, ist das oben Genannte nicht für multimodale Sammlungen geeignet. Wir können dieses Problem beheben, ganz einfach:

public static List<Integer> mode(final int[] numbers) { 
    final List<Integer> modes = new ArrayList<Integer>(); 
    final Map<Integer, Integer> countMap = new HashMap<Integer, Integer>(); 

    int max = -1; 

    for (final int n : numbers) { 
     int count = 0; 

     if (countMap.containsKey(n)) { 
      count = countMap.get(n) + 1; 
     } else { 
      count = 1; 
     } 

     countMap.put(n, count); 

     if (count > max) { 
      max = count; 
     } 
    } 

    for (final Map.Entry<Integer, Integer> tuple : countMap.entrySet()) { 
     if (tuple.getValue() == max) { 
      modes.add(tuple.getKey()); 
     } 
    } 

    return modes; 
} 

ADDITION

Wenn Sie Java 8 oder höher verwenden, können Sie bestimmen auch die Modi wie folgt aus:

public static List<Integer> getModes(final List<Integer> numbers) { 
    final Map<Integer, Long> countFrequencies = numbers.stream() 
      .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); 

    final long maxFrequency = countFrequencies.values().stream() 
      .mapToLong(count -> count) 
      .max().orElse(-1); 

    return countFrequencies.entrySet().stream() 
      .filter(tuple -> tuple.getValue() == maxFrequency) 
      .map(Map.Entry::getKey) 
      .collect(Collectors.toList()); 
} 
+0

Dank, aber ich würde etwas aus der Box zu verwenden, es vorziehen, wenn möglich – user339108

+0

@Stephen C. darüber Sorry, ich den Link wieder aktualisiert. –

+0

Diese Klasse wird Probleme haben, wenn Sie ein sehr großes Array haben oder Werte im laufenden Betrieb berechnen müssen. Es kann ohne ein Array für Mittelwert und Standardabweichung geschrieben werden; nicht so sicher für Median und Modus. – duffymo

2

Der MODE-Algorithmus berücksichtigt keine Fälle mit mehr als einem Modus (bimodal, trimodal, ...) - dies geschieht, wenn mehr als eine Zahl in der gleichen Anzahl wie maxCount auftritt. In Anbetracht dessen sollte es ein Array anstelle eines einzelnen int-Werts zurückgeben.

-1
public class Mode { 
    public static void main(String[] args) { 
     int[] unsortedArr = new int[] { 3, 1, 5, 2, 4, 1, 3, 4, 3, 2, 1, 3, 4, 1 ,-1,-1,-1,-1,-1}; 
     Map<Integer, Integer> countMap = new HashMap<Integer, Integer>(); 

     for (int i = 0; i < unsortedArr.length; i++) { 
      Integer value = countMap.get(unsortedArr[i]); 

      if (value == null) { 
       countMap.put(unsortedArr[i], 0); 
      } else { 
       int intval = value.intValue(); 
       intval++; 
       countMap.put(unsortedArr[i], intval); 
      } 
     } 

     System.out.println(countMap.toString()); 

     int max = getMaxFreq(countMap.values()); 
     List<Integer> modes = new ArrayList<Integer>(); 

     for (Entry<Integer, Integer> entry : countMap.entrySet()) { 
      int value = entry.getValue(); 
      if (value == max) 
       modes.add(entry.getKey()); 
     } 
     System.out.println(modes); 
    } 

    public static int getMaxFreq(Collection<Integer> valueSet) { 
     int max = 0; 
     boolean setFirstTime = false; 

     for (Iterator iterator = valueSet.iterator(); iterator.hasNext();) { 
      Integer integer = (Integer) iterator.next(); 

      if (!setFirstTime) { 
       max = integer; 
       setFirstTime = true; 
      } 
      if (max < integer) { 
       max = integer; 
      } 
     } 
     return max; 
    } 
} 

Testdaten

Modes {1,3} für {3, 1, 5, 2, 4, 1, 3, 4, 3, 2, 1, 3, 4, 1 };
Modi {-1} für {3, 1, 5, 2, 4, 1, 3, 4, 3, 2, 1, 3, 4, 1, -1, -1, -1, -1, - 1};

0
public static Set<Double> getMode(double[] data) { 
      if (data.length == 0) { 
       return new TreeSet<>(); 
      } 
      TreeMap<Double, Integer> map = new TreeMap<>(); //Map Keys are array values and Map Values are how many times each key appears in the array 
      for (int index = 0; index != data.length; ++index) { 
       double value = data[index]; 
       if (!map.containsKey(value)) { 
        map.put(value, 1); //first time, put one 
       } 
       else { 
        map.put(value, map.get(value) + 1); //seen it again increment count 
       } 
      } 
      Set<Double> modes = new TreeSet<>(); //result set of modes, min to max sorted 
      int maxCount = 1; 
      Iterator<Integer> modeApperance = map.values().iterator(); 
      while (modeApperance.hasNext()) { 
       maxCount = Math.max(maxCount, modeApperance.next()); //go through all the value counts 
      } 
      for (double key : map.keySet()) { 
       if (map.get(key) == maxCount) { //if this key's value is max 
        modes.add(key); //get it 
       } 
      } 
      return modes; 
     } 

     //std dev function for good measure 
     public static double getStandardDeviation(double[] data) { 
      final double mean = getMean(data); 
      double sum = 0; 
      for (int index = 0; index != data.length; ++index) { 
       sum += Math.pow(Math.abs(mean - data[index]), 2); 
      } 
      return Math.sqrt(sum/data.length); 
     } 


     public static double getMean(double[] data) { 
     if (data.length == 0) { 
      return 0; 
     } 
     double sum = 0.0; 
     for (int index = 0; index != data.length; ++index) { 
      sum += data[index]; 
     } 
     return sum/data.length; 
    } 

//by creating a copy array and sorting it, this function can take any data. 
    public static double getMedian(double[] data) { 
     double[] copy = Arrays.copyOf(data, data.length); 
     Arrays.sort(copy); 
     return (copy.length % 2 != 0) ? copy[copy.length/2] : (copy[copy.length/2] + copy[(copy.length/2) - 1])/2; 
    } 
Verwandte Themen