2010-07-13 54 views
0

我有一個文本文件:Java的特定時間平均

DATE 20090105 
1 2.25 1.5 
3 3.6 0.099 
4 3.6 0.150 
6 3.6 0.099 
8 3.65 0.0499 
DATE 20090105 
DATE 20090106 
1 2.4 1.40 
2 3.0 0.5 
5 3.3 0.19 
7 2.75 0.5 
10 2.75 0.25 
DATE 20090106 
DATE 20090107 
2 3.0 0.5 
2 3.3 0.19 
9 2.75 0.5 
DATE 20100107 

的每一天,我有:

​​3210

我想在一個特定的時間上最大的時間尺度制定出平均方差。

該文件很大,這只是一個小編輯樣本。這意味着我不知道最新的時間和最早的時間(大約在2600年),最近的時間可能在50000年左右。

因此,例如在所有的日子裏,我只有在時間t = 1時有1個值,因此那是當時的平均差異。

在時間t = 2,在第一天,時間t = 2時的方差取值爲1.5,因爲它持續到t = 3,第二天取值= 0.5,第三天取值((0.5 + 0.18)/ 2)。因此,時間t = 2的所有日子的平均方差是當時所有方差的總和除以當時的不同方差的數量。

對於當天的最後一次,它需要的時間尺度是t = 1。

我只是想知道我會如何去做這件事。

作爲一個完整的初學者,我發現這很複雜。我是一名Uni學生,但大學已經完成,我正在學習Java,以便在暑假期間幫助我的爸爸生意。所以任何關於解決方案的幫助都非常感謝。

+3

我覺得你沒有得到答案,因爲你的問題描述很難理解。請儘量讓我們這些對凡人更清楚些! – 2010-07-13 14:02:19

+0

另外,你期待什麼樣的輸出?你想寫出一個包含每個可能時間變化的文件嗎?或者您是否會查詢特定時間,並想在當時查找或計算答案? – 2010-07-13 14:07:07

+0

7號,你的第一次是2.那麼你的變化在時間1應該是什麼樣子? – 2010-07-13 14:09:19

回答

0

好吧,我有一個代碼可以工作。但它需要很長時間(大約7個月的時間,每天有30,000次差異),因爲它必須循環很多次。還有其他更好的建議嗎?

我的意思是這個代碼的東西看似簡單,需時約24-28小時......

包VarPackage;

import java.io.BufferedReader; import java.io.FileReader; import java.util.ArrayList;

公共類的ReadText {

public static void main(String[] args) throws Exception { 
    String inputFileName="C:\\MFile"; 


    ArrayList<String> fileLines = new ArrayList<String>(); 
    FileReader fr; 
    BufferedReader br; 

    // Time 
    int t = 1; 


    fr = new FileReader(inputFileName); 
    br = new BufferedReader(fr); 
    String line; 


    while ((line=br.readLine())!=null) { 
    fileLines.add(line); 
    } 

    AvgVar myVar = new AvgVar(fileLines); 

    for(t=1; t<10; t++){ 
    System.out.print("Average Var at Time t=" + t + " = " + myVar.avgVar(t)+"\n"); 

}

}}

======================= ============

NewClass

package VarPackage;

import java.util。數組列表;

公共類AvgVar {0}類變量 private ArrayList inputData = new ArrayList();

//構造函數 AvgVar(ArrayList fileData){input:inputData = fileData; }

public double avgVar(int time){ 

double avgVar = 0; 

ArrayList<double[]> avgData = avgDuplicateVars(inputData); 

for(double[] arrVar : avgData){ 
avgVar += arrVar[time-1]; 
//System.out.print(arrVar[time-1] + "," + arrVar[time] + "," + arrVar[time+1] + "\n"); 
//System.out.print(avgVar + "\n"); 
} 

avgVar /= numDays(inputData); 

return avgVar; 
} 

private int numDays(ArrayList<String> varData){ 

int n = 0; 
int flag = 0; 

爲(字符串行:VARDATA){

String[] myData = line.split(" "); 

if(myData[0].equals("DATE") && flag == 0){ 

    flag = 1; 

    } 
    else if(myData[0].equals("DATE") && flag == 1){ 

    n = n + 1; 
    flag = 0; 

    } 

}

回報N;

} 

private ArrayList<double[]> avgDuplicateVars(ArrayList<String> varData){ 

ArrayList<double[]> avgData = new ArrayList<double[]>(); 

double[] varValue = new double[86400]; 
double[] varCount = new double[86400]; 

int n = 0; 
int flag = 0; 

爲(字符串ILINE:VARDATA){

String[] nLine = iLine.split(" "); 
    if(nLine[0].equals("DATE") && flag == 0){ 

    for (int i=0; i<86400; i++){ 
    varCount[i] = 0; 
    varValue[i] = 0; 
    } 

    flag = 1; 

    } 
    else if(nLine[0].equals("DATE") && flag == 1){ 

    for (int i=0; i<86400; i++){ 
    if (varCount[i] != 0){ 
    varValue[i] /= varCount[i]; 
    } 
    } 

    varValue = fillBlankSpreads(varValue, 86400); 

    avgData.add(varValue.clone()); 

    flag = 0; 

    } 
    else{ 

    n = Integer.parseInt(nLine[0])-1; 

    varValue[n] += Double.parseDouble(nLine[2]); 
    varCount[n] += 1; 

    } 

}

返回avgData;

} 

private double[] fillBlankSpreads(double[] varValue, int numSpread){ 
//Filling the Data with zeros to make the code faster 
for (int i=1; i<numSpread; i++){ 
if(varValue[i] == 0){ 
varValue[i] = varValue[i-1]; 
} 
} 

return varValue; 
} 

}

+0

問題出現在for循環,它在一天中每秒鐘經歷86400次迭代。 我不知道,也許是aray數組的數組? 編碼很好,正如我所說的那樣,我得到了正確的答案,但它並沒有很好地讓我得到正確的答案。所以我把它慢一點 – 2010-07-15 09:56:49

0

你有下面按照步驟

  • 創建一個類的日期和TRV財產
  • 上面瞭解創建類
  • 列表讀取使用IO類的文件。
  • 閱讀塊,並通過「DATE」通過空間轉換爲字符串
  • 分割整個字符串和修剪
  • 斯普利特(」「)
  • 的第一個項目將是你的約會。
  • 將所有其他項目轉換爲浮點數並查找平均值。
  • 將它添加到列表。現在你有一個日常平均的列表。
  • 您可以將其保存到磁盤並查詢您的所需數據。

編輯 你已編輯你的問題,現在它看起來總的不同。 我認爲你需要幫助解析文件。糾正我,如果我錯了。

+0

感謝您的回答,但我不認爲這就是我所追求的。 我想要在整個特定時間的平均值。 例如。 星期一人們在商店 上午9:00 5 上午9:05 10 上午9:10 15 週二 上午9:00 1 上午9:05 2 上午9:10 1 所以平均模型predit人會多少是在這些時間的店鋪如下。 上午9:00 3 上午9:05 6 上午9:10 8 因爲我已經取得了商店當時的平均人數。 我想你所描述的只是日常的平均值? 謝謝 – 2010-07-13 14:17:19

+0

然後你需要解析文件並將數據傳輸到數據庫(ex mySQL)。然後你可以使用你的參數 – Manjoor 2010-07-13 14:35:52

+0

查詢它,我幾乎不知道,我一直在做Java的一個星期,只是試圖幫助。我只是試圖儘快完成這項工作 – 2010-07-13 15:00:47

0

如果我的理解正確,那麼您的移動平均值就是根據數據流計算的。 我寫的以下課程提供了一些這樣的統計數據。

  • 均線
  • 腐爛的平均水平(反映平均值的最後幾個樣本的基礎上,衰減因子)。
  • 移動方差
  • 衰減方差
  • 最小值和最大值

希望它有幫助。

/** 
* omry 
* Jul 2, 2006 
* 
* Calculates: 
* 1. running average 
* 2. running standard deviation. 
* 3. minimum 
* 4. maximum 
*/ 
public class Statistics 
{ 
    private double m_lastValue; 
    private double m_average = 0; 
    private double m_stdDevSqr = 0; 

    private int m_n = 0; 
    private double m_max = Double.NEGATIVE_INFINITY; 
    private double m_min = Double.POSITIVE_INFINITY; 

    private double m_total; 

    // decay factor. 
    private double m_d; 
    private double m_decayingAverage; 
    private double m_decayingStdDevSqr; 

    public Statistics() 
    { 
     this(2); 
    } 

    public Statistics(float d) 
    { 
     m_d = d; 
    } 

    public void addValue(double value) 
    { 
     m_lastValue = value; 
     m_total += value; 

     // see http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance 
     m_n++; 
     double delta = value - m_average; 
     m_average = m_average + delta/(float)m_n; 
     double md = (1/m_d); 
     if (m_n == 1) 
     { 
      m_decayingAverage = value; 
     } 
     m_decayingAverage = (md * m_decayingAverage + (1-md)*value); 

     // This expression uses the new value of mean 
     m_stdDevSqr = m_stdDevSqr + delta*(value - m_average); 

     m_decayingStdDevSqr = m_decayingStdDevSqr + delta*(value - m_decayingAverage); 

     m_max = Math.max(m_max, value); 
     m_min = Math.min(m_min, value);  
    } 

    public double getAverage() 
    { 
     return round(m_average); 
    } 

    public double getDAverage() 
    { 
     return round(m_decayingAverage); 
    } 

    public double getMin() 
    { 
     return m_min; 
    } 

    public double getMax() 
    { 
     return m_max; 
    } 

    public double getVariance() 
    { 
     if (m_n > 1) 
     { 
      return round(Math.sqrt(m_stdDevSqr/(m_n - 1))); 
     } 
     else 
     { 
      return 0; 
     } 
    } 


    public double getDVariance() 
    { 
     if (m_n > 1) 
     { 
      return round(Math.sqrt(m_decayingStdDevSqr/(m_n - 1))); 
     } 
     else 
     { 
      return 0; 
     } 
    } 

    public int getN() 
    { 
     return m_n; 
    } 

    public double getLastValue() 
    { 
     return m_lastValue; 
    } 

    public void reset() 
    { 
     m_lastValue = 0; 
     m_average = 0; 
     m_stdDevSqr = 0; 
     m_n = 0; 
     m_max = Double.NEGATIVE_INFINITY; 
     m_min = Double.POSITIVE_INFINITY; 
     m_decayingAverage = 0; 
     m_decayingStdDevSqr = 0; 
     m_total = 0; 
    } 

    public double getTotal() 
    { 
     return round(m_total); 
    } 

    private double round(double d) 
    { 
     return Math.round((d * 100))/100.0; 
    } 
} 
+0

嗨,感謝您的意見,這是非常有用的,可以幫助我瞭解如何編程移動平均值。 但是我在一個特定的時間平均AT。不是移動平均線。 但是再次感謝你,這可能會幫助我完成下一個任務! – 2010-07-13 14:25:45

+0

好吧,特定時間的平均值是在插入所有值之前由getAverage()返回的值。 – 2010-07-13 15:27:50

+0

對於我在下面添加的代碼,你有什麼建議? – 2010-07-14 10:32:47

0

我想我明白了。你想

  1. 找到在每天特定時間t的平均方差 - 這是由當日的最高時間戳小於t
  2. 處理的情況下給出,其中在同一時間多個讀數通過平均他們。
  3. 時刻t

找到所有天數的平均方差所以我建議,一旦你解析數據@Manjoor建議,那麼,(僞!)

function getAverageAt(int t) 
    float lastvariance = 0; // what value to start on, 
         // if no variance is specified at t=1 on day 1 
         // also acts as accumulator if several values at one 
         // timestamp 
    float allDaysTotal = 0; // cumulative sum of the variance at time t for all days 
    for each day { 
    float time[], rating[], variance[]; 
    //read these from table 
    int found=0; //how many values found at time t today 
    for(int i=0;i<time.length;i++){ 
     if(time[i]<t) lastvariance=variance[i]; // find the most recent value 
         // before t. 
         // This relies on your data being in order! 
     else if(time[i]==t){ // time 
     found++; 
     if (found==1) lastvariance=variance[i]; // no previous occurrences today 
     else lastvariance+=variance[i]; 
     } 
     else if(time[i]>t) break; 
    } 
    if(found>1) lastvariance/=found; // calculate average of several simultaneous 
    // readings, if more than one value found today at time t. 
    // Note that: if found==0, this means you're using a previous 
    // timestamp's value. 
    // Also note that, if at t=1 you have 2 values of variance, that 
    // averaged value will not continue over to time t. 
    // You could easily reimplement that if that's the behaviour you desire, 
    // the code is similar, but putting the time<t condition along with the 
    // time==t condition 
    allDaysTotal+=lastvariance; 
    } 
    allDaysMean = allDaysTotal/nDays 

你的問題並不是一個簡單的例子,正如我指出的那樣。

+0

謝謝你的幫助。我不知道解析是什麼,但我相信我能找到它。 這是相當複雜嗎?我的意思是經過一個星期的編碼,我應該能夠做到這一點? – 2010-07-14 10:49:35

+0

還有什麼意思是小於t的最高時間戳? 我的差異將取值在1和10之間,10的最終差異持續1秒直到11. 因此,對於時間t = 3的平均方差,我將在時間t = 3時取所有差異並且如果在時間t = 3時沒有指定的值,則意味着它將先前的可用時間方差作爲其自己的方差。 – 2010-07-14 10:54:01

+0

是的。每個數據點的「時間戳」是數據的第一列。因此,「當天最低時間戳t小於」是一種更符合計算機的寫作方式。就你而言,解析就是將文本轉換爲數字表格。如果您按照我所說的步驟執行任務,那麼任務並不複雜,但您需要考慮像上次記錄的時間點本身就是多個數據點的平均值這樣的捕獲情況。我的意思是,如果你剝下我的代碼,你可以得到10行代碼! – 2010-07-14 23:46:14