java - Get median values from sorted data -


i have set of sorted (ascending) data in format below:

| category | value | s.d. | |        |  0.1  | 0.1  | |        |  0.2  | 0.05 | |        |  1.3  | 0.08 | |     b    |  0.1  | 0.01 | |     b    |  0.2  | 0.08 | |     b    |  0.6  | 0.9  | |     b    |  0.7  | 0.01 | |     b    |  0.9  | 0.05 | |     b    |  1.1  | 0.6  | |     c    |  0.5  | 0.3  | |     c    |  0.9  | 0.04 | |     c    |  1.0  | 0.14 | |     c    |  2.1  | 0.1  | etc... 

there 300 rows of this. have imported csv , have sorted list. example data.get(1).getcategory() results in "a", , data.get(2).getvalue() results in "0.2" (it string using library.)

the data subject change. need calculate median value each category, , print each median value it's category name. there number of entries, middle value smallest s.d. should used. example, using above data:

"a: 0.2" "b: 0.7" "c: 0.9" 

here single pass on sorted list solution:

import java.util.arraylist; import java.util.collections; import java.util.list;  public class medians {   public static void printmedians(list<row> rows) {     if (rows.size() == 0) return;     collections.sort(rows);     int currentcategoryindex = 0;     string currentcategory = rows.get(0).category;     (int = 0; < rows.size(); i++) {       if (i == rows.size() - 1           || !currentcategory.equals(rows.get(i + 1).category)) {         int categorysize = + 1 - currentcategoryindex;         int medianindex = currentcategoryindex + categorysize / 2;         double median;          if (categorysize % 2 == 0) {           median = rows.get(medianindex - 1).stddev < rows.get(medianindex).stddev               ? rows.get(medianindex - 1).value               : rows.get(medianindex).value;         } else {           median = rows.get(medianindex).value;         }          system.out.printf("%s: %.1f%n", currentcategory, median);          if (i < rows.size() - 1) {           currentcategory = rows.get(i + 1).category;           currentcategoryindex = + 1;         }       }     }   }    private static class row implements comparable<row> {     private final string category;     private final double value;     private final double stddev;      public row(string category, double value, double standarddeviation) {       this.category = category;       this.value = value;       this.stddev = standarddeviation;     }      @override     public int compareto(row o) {       if (category.equals(o.category)) {         return value == o.value ? 0 : value > o.value ? 1 : - 1;       }       return category.compareto(o.category);     }   }    public static void main(string[] args) {     list<row> rows = new arraylist<>();     rows.add(new row("a", 0.2, 0.05));     rows.add(new row("a", 1.3, 0.08));     rows.add(new row("a", 0.1, 0.1));      rows.add(new row("b", 0.6, 0.9));     rows.add(new row("b", 1.1, 0.6));     rows.add(new row("b", 0.7, 0.01));     rows.add(new row("b", 0.9, 0.05));     rows.add(new row("b", 0.1, 0.01));     rows.add(new row("b", 0.2, 0.08));      rows.add(new row("c", 0.5, 0.3));     rows.add(new row("c", 1.0, 0.14));     rows.add(new row("c", 2.1, 0.1));     rows.add(new row("c", 0.9, 0.04));     printmedians(rows);   } } 

but 1 more:

import java.util.arraylist; import java.util.collections; import java.util.hashmap; import java.util.list; import java.util.map; import java.util.treemap;  public class categorymediancalculator {   private final map<string, list<row>> categories = new hashmap<>();    public void addrow(string category, double value, double stddev) {     list<row> rows = categories.get(category);     if (rows == null) {       rows = new arraylist<>();       categories.put(category, rows);     }     rows.add(new row(category, value, stddev));   }    public map<string, double> getmedians() {     map<string, double> result = new treemap<>();     (map.entry<string, list<row>> entry: categories.entryset()) {       result.put(entry.getkey(), getmedian(entry.getvalue()));     }     return result;   }    private static double getmedian(list<row> rows) {     collections.sort(rows);     int index = rows.size() / 2;     if (rows.size() % 2 == 0) {       return rows.get(index - 1).stddev < rows.get(index).stddev           ? rows.get(index - 1).value           : rows.get(index).value;     } else {       return rows.get(index).value;     }   }    private static class row implements comparable<row> {     private final string category;     private final double value;     private final double stddev;      public row(string category, double value, double stddev) {       this.category = category;       this.value = value;       this.stddev = stddev;     }      @override     public int compareto(row o) {       return value == o.value ? 0 : value > o.value ? 1 : - 1;     }   }    public static void main(string[] args) {     categorymediancalculator calc = new categorymediancalculator();     calc.addrow("a", 0.2, 0.05);     calc.addrow("a", 1.3, 0.08);     calc.addrow("a", 0.1, 0.1);      calc.addrow("b", 0.6, 0.9);     calc.addrow("b", 1.1, 0.6);     calc.addrow("b", 0.7, 0.01);     calc.addrow("b", 0.9, 0.05);     calc.addrow("b", 0.1, 0.01);     calc.addrow("b", 0.2, 0.08);      calc.addrow("c", 0.5, 0.3);     calc.addrow("c", 1.0, 0.14);     calc.addrow("c", 2.1, 0.1);     calc.addrow("c", 0.9, 0.04);      (map.entry<string, double> median : calc.getmedians().entryset()) {       system.out.printf("%s: %.1f%n", median.getkey(), median.getvalue());     }   } } 

Comments

Popular posts from this blog

c++ - QTextObjectInterface with Qml TextEdit (QQuickTextEdit) -

javascript - angular ng-required radio button not toggling required off in firefox 33, OK in chrome -

xcode - Swift Playground - Files are not readable -