How to detect outliers in an ArrayList

后端 未结 8 928
旧时难觅i
旧时难觅i 2021-01-14 02:54

I\'m trying to think of some code that will allow me to search through my ArrayList and detect any values outside the common range of \"good values.\"

Example: 100 1

8条回答
  •  礼貌的吻别
    2021-01-14 03:37

    package test;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class Main {
        public static void main(String[] args) {
            List data = new ArrayList();
            data.add((double) 20);
            data.add((double) 65);
            data.add((double) 72);
            data.add((double) 75);
            data.add((double) 77);
            data.add((double) 78);
            data.add((double) 80);
            data.add((double) 81);
            data.add((double) 82);
            data.add((double) 83);
            Collections.sort(data);
            System.out.println(getOutliers(data));
        }
    
        public static List getOutliers(List input) {
            List output = new ArrayList();
            List data1 = new ArrayList();
            List data2 = new ArrayList();
            if (input.size() % 2 == 0) {
                data1 = input.subList(0, input.size() / 2);
                data2 = input.subList(input.size() / 2, input.size());
            } else {
                data1 = input.subList(0, input.size() / 2);
                data2 = input.subList(input.size() / 2 + 1, input.size());
            }
            double q1 = getMedian(data1);
            double q3 = getMedian(data2);
            double iqr = q3 - q1;
            double lowerFence = q1 - 1.5 * iqr;
            double upperFence = q3 + 1.5 * iqr;
            for (int i = 0; i < input.size(); i++) {
                if (input.get(i) < lowerFence || input.get(i) > upperFence)
                    output.add(input.get(i));
            }
            return output;
        }
    
        private static double getMedian(List data) {
            if (data.size() % 2 == 0)
                return (data.get(data.size() / 2) + data.get(data.size() / 2 - 1)) / 2;
            else
                return data.get(data.size() / 2);
        }
    }
    

    Output: [20.0]

    Explanation:

    • Sort a list of integers, from low to high
    • Split a list of integers into 2 parts (by a middle) and put them into 2 new separate ArrayLists (call them "left" and "right")
    • Find a middle number (median) in both of those new ArrayLists
    • Q1 is a median from left side, and Q3 is the median from the right side
    • Applying mathematical formula:
    • IQR = Q3 - Q1
    • LowerFence = Q1 - 1.5*IQR
    • UpperFence = Q3 + 1.5*IQR
    • More info about this formula: http://www.mathwords.com/o/outlier.htm
    • Loop through all of my original elements, and if any of them are lower than a lower fence, or higher than an upper fence, add them to "output" ArrayList
    • This new "output" ArrayList contains the outliers

提交回复
热议问题