2016-05-26 3 views
3

背景:私は、Apache Commonsの数学を使用して救急車の統計を決定しようとしています 。私は1つの救急車について非常に基本的な単変量統計を行うことができますが、私は自分の艦隊内のすべての救急車の統計を決定したいときに立ち往生します。ループ

目標: 私の目標は、その後の統計情報に情報を解析、JDBCを使用して、基本的な結果セットを生成することです。例えば、私は結果セットを取って、救急車を示すテーブル、2014年の平均、2015年の平均をヘッダーのように見せたいと思います。 表の詳細は、各救急車と各ヘッダーの平均値を示すだろう

<table> 
 
<tr><th>ambulance</th><th>average response time for year 2014</th><th>average response time for year 2015</th></tr> 
 
<tr><td>Medic1</td><td>62</td><td>74</td></tr> 
 
<tr><td>Medic2</td><td>83</td><td>79</td></tr> 
 
<tr><td>Medic3</td><td>68</td><td>71</td></tr> 
 
</table>

しようとしました擬似コード: 次のようになり擬似コード。 )暦年の平均応答時間の変数を割り当てます。 )暦年が2014年の場合は結果セット内のすべての救急車をループして平均を計算します。 3.)暦年の2015平均応答時間の変数を割り当てます。 4.)すべての救急車を巡回し、暦年が2015であれば平均を計算します。 5)出力救急車、2014年の平均応答時間、2015

コメントの平均応答時間: これは良いスタートになります。少なくとも論理と形式は、年々の相違を決定するなど、より洗練された分析を行うために存在します。しかし、私は立ち往生しています。私は平均を生成するために各救急車に反復を行う方法がわかりません。

私は、各救急車の平均を生成するSQLクエリを書くことができます。しかし、私はApache Commons Mathを使っています。なぜなら、Skew、Kurtosisなどの手段を提供しているからです。この段落の上に表示されているのは、より複雑なものの単純化された例です。

Javaコード:

package EMSResearch; 

import java.sql.*; 
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; 

public class EMSResearch 
{ 

    public static void main(String[] args) 
    { 
     Connection conn = null; 
     Statement stmt = null; 
     try 
     { 
      conn = DriverManager.getConnection("jdbc:sqlserver://MyDatabase;database=Emergencies;integratedsecurity=false;user=MyUserName;password=MyPassword"); 
      stmt = conn.createStatement(); 
      String strSelect = "SELECT EmergencyID, YearOfCall, ResponseTime, Ambulance"; 
      ResultSet rset = stmt.executeQuery(strSelect); 

      DescriptiveStatistics ds = new DescriptiveStatistics(); 
/*the following code does the job of generating average response time for Medic1 for year 2015. But I want it to loop through and get all the ambulances for year 2015*/ 
      while (rset.next()) 
      { 
       if (rset.getString("Ambulance").equals("Medic1") && rset.getInt("YearOfCall") == 2015) 
       { 
        String event = rset.getString("I_EventNumber"); 
        int year = rset.getInt("YearOfCall"); 
        int responseTime = rset.getInt("ResponseTime"); 
        String truck = rset.getString("Ambulance"); 
        ds.addValue(responseTime); 
       } 
      } 
      System.out.println("mean average value " + ds.getMean()); 


     } catch (SQLException ex) 
     { 
      ex.printStackTrace(); 
     } finally 
     { 
+0

代わりに[SQLウィンドウ関数](https://msdn.microsoft.com/en-us/library/ms189461%28v=sql.110%29.aspx)を使用することを検討してください。 –

+0

それは私が通常行うことですが、この場合、私はApache Commons Mathを使いたいと思っていました。スキューと尖度のためのメソッドがあるからです。また、熟練したら、より多くのクールな統計機能を実行できます。 –

答えて

0

このようなものが役立つかもしれません。マップを使ってすべての年とトラックのすべてのデータを保存すれば、あなたは私が必要とするすべてを得ることができます。 このコードは完全には焼かれていませんが、概念はかなり甘いと思います。

private static void getstats(ResultSet rset) throws SQLException { 
    Map<Integer, Map<String, DescriptiveStatistics>> stats = new HashMap<>(); 
    while (rset.next()) { 

     String event = rset.getString("I_EventNumber"); 
     int year = rset.getInt("YearOfCall"); 
     int responseTime = rset.getInt("ResponseTime"); 
     String truck = rset.getString("Ambulance"); 
     if (stats.containsKey(year)) { 
     Map<String, DescriptiveStatistics> get = stats.get(year); 
     if (get.containsKey(truck)) { 
      get.get(truck).addValue(responseTime); 
     } else { 
      Map<String, DescriptiveStatistics> newmap = new HashMap<>(); 
      DescriptiveStatistics newDs = new DescriptiveStatistics(); 
      newDs.addValue(responseTime); 
      newmap.put(truck, newDs); 
     } 

     } else { 

     Map<String, DescriptiveStatistics> newmap = new HashMap<>(); 
     DescriptiveStatistics newDs = new DescriptiveStatistics(); 
     newDs.addValue(responseTime); 
     newmap.put(truck, newDs); 
     stats.put(year, newmap); 
     } 

    } 
    for(Integer year : stats.keySet()){ 
     for(String truck : stats.get(year).keySet()){ 
     DescriptiveStatistics ds = stats.get(year).get(truck); 
     /**do stuff with the ds for this year and this truck**/ 

     } 
    } 

    } 
+0

ありがとうございました。私は大学の教科書を取り出し、地図を読み上げるつもりです。私は初心者のプログラマーです。ところで、トミーボーイは陽気な映画だと思う。 –

+0

マップはキー→値構造体です。 get(...)メソッドはキーを受け取り、ジェネリック型argsで設定した値を返します。地図は強力です、私はあなたがそれらを知って得ることをお勧めします! – markg

0

マークが言ったように、Mapが大いに役立ちます。しかしちょっと追加するだけで、データをグループ分けして意味のある方法でまとめることもできます。あなたは、本質的に、あなたの1つのデータセットに追加し、データが特定の条件を満たしているかどうかを判断されて、今やっていること

DescriptiveStatistics ds = new DescriptiveStatistics(); 

while (rset.next()) 
{ 
    if (rset.getString("Ambulance").equals("Medic1") && rset.getInt("YearOfCall") == 2015) 
    { 
     String event = rset.getString("I_EventNumber"); 
     int year = rset.getInt("YearOfCall"); 
     int responseTime = rset.getInt("ResponseTime"); 
     String truck = rset.getString("Ambulance"); 
     ds.addValue(responseTime); 
    } 
} 

:たとえば、あなたの現在の実装では、これを含んでいます。しかし、別の基準を確認したい場合は、別のデータセットを初期化し、別のif文を追加し、そこにコードをコピーする必要があります。 はスケーラブルではありません

は代わりに、あなたがして、グループにあなたのデータを使用することができるオブジェクトを作成することを検討:

public class DataPoint { 
    // Consider private members with public getters/setters. 
    public String ambulance; 
    public int year; 

    public DataPoint(String ambulance, int year) { 
     this.ambulance = ambulance; 
     this.year = year; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result 
       + ((ambulance == null) ? 0 : ambulance.hashCode()); 
     result = prime * result + year; 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     DataPoint other = (DataPoint) obj; 
     if (ambulance == null) { 
      if (other.ambulance != null) 
       return false; 
     } else if (!ambulance.equals(other.ambulance)) 
      return false; 
     if (year != other.year) 
      return false; 
     return true; 
    } 
} 

hashCode()equals()オーバーライドが重要ですが、この議論に対して接線方向にあります。基本的に、マップは、同じパラメータを持つ2つの異なるオブジェクトが同じであることを検出して判断できることを確認します。

新しいDataPointオブジェクトでは、受け取ったデータを特定のデータセットにマップできます。だから私は、上記の概説実装に置き換えられる:

Map<DataPoint, DescriptiveStatistics> map = new HashMap<DataPoint, DescriptiveStatistics>(); 

while (rset.next()) 
{ 
    // Get parameters we differentiate based on. 
    String truck = rset.getString("Ambulance"); 
    int year = rset.getInt("YearOfCall"); 

    // Create the data point. 
    DataPoint point = new DataPoint(truck, year); 

    // Get data set for point; if it doesn't exist, create it. 
    if (map.get(point) == null) { 
     map.put(new DescriptiveStatistics()); 
    } 
    DescriptiveStatistics ds = map.get(point); 

    // Add the data of interest to the given data set. 
    int responseTime = rset.getInt("ResponseTime"); 
    ds.addValue(responseTime); 
} 

するとwhileループが終了すると、あなたは、特定のデータポイントおよびそれに関連するデータ・セットのマッピングに満たされた地図を持っています。そこからわずかマップエントリを反復処理し、あなたがデータセットでやりたいことができます:少し明確

for (Entry<DataPoint, DescriptiveStatistics> entry : map.entrySet()) 
... 

希望。