2010-07-13 211 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