寻找更智能的方式读取和写入时间序列数据 [英] Looking for Smarter way to read and write time series data
问题描述
你好朋友,
我是这个论坛和C#编程的新手.我自己教过一点C#.
我正在这个小应用程序中工作,其中有一个带有
的winForm
-组合框(cb值为0,1,2 ..... 25)和
-一个dataGridView. dataGridView列是根据用户选择的值填充的(直到运行时我才知道).用户将数据复制并粘贴到dataGridView中,如下所示:
Hello Friends,
I am a totally newbie to this forum and to C# programming as well. Taught little bit of C# myself.
I am working in this little application where I have a winForm with
- a combobox (with cb values 0,1,2.....25) and
- a dataGridView. The dataGridView columns are populated based on the value selected by the user (which I won''t know until runtime). User copies and pastes data into the dataGridView which will look something like this:
col1 col2 col3 col4 col4 col 5 col6 ........col30
-----------------------------------------------------------
2001 08 25 14 35 0.00 0.00
2001 08 25 14 40 0.00 0.00
2001 08 25 14 45 0.00 0.00
2001 08 25 14 50 0.00 0.00
2001 08 25 14 55 0.00 0.00
2001 08 25 15 00 0.00 0.00
2001 08 25 15 05 0.00 0.00
2001 08 25 15 10 0.00 0.00
2001 08 25 15 15 0.00 0.00
2001 08 25 15 20 0.00 0.00
2001 08 25 15 25 0.00 0.00
2001 08 25 15 30 0.00 0.10
2001 08 25 15 35 0.15 0.00
2001 08 25 15 40 0.30 0.00
2001 08 25 15 45 0.20 0.00
2001 08 25 15 50 0.10 0.00
2001 08 25 15 55 0.00 0.00
2001 08 25 16 00 0.00 0.00
2001 08 25 16 05 0.00 0.90
2001 08 25 16 10 0.00 0.00
2001 08 25 16 15 0.00 0.00
因此,前5列始终显示着年,月,日,小时和分钟(因此我将其称为日期列").除此之外,其他列将具有我需要处理的值(我称它们为值列").
阅读正在进行...我将稍后发布代码(我怀疑自己是用聪明的方式完成的:-))
现在,
我需要摆脱在每个值列"(第6列及以后的列)中具有零值的行...如果我有5个值列"并且这些列中的每一个都具有0个值,然后删除该行.但是,如果该行中的任何值列"具有非零值,则不要删除.
-
这是另一个条件:
-
在两个非零块之间,有一个由用户定义的最小时间间隔.例如,如果用户选择间隔时间为2小时,那么如果该行距其上方的非零行2小时以内,则我将使行保持全零值.
结果谁看起来像这样:
So the first 5 columns are always there which read year, month, day, hour and minutes(so I call them ''date columns''). Beyond that, other column(s) will have the value I need to work on (and I call them ''value columns'').
Reading is working... I will post the code in a bit (I doubt I am doing it in smart way :-) )
NOW,
I need to get rid of rows that have zero values in each of the ''value columns'' (column6 and beyond)... meaining if I have 5 ''value columns'' and if each of these columns have 0 values, then delete that row. But do not delete if any one of the ''value columns'' has a non-zero value on that row.
-
Here is another condition:
-
Between two non-zero blocks there is a minimum time separation defined by the user. For eg if the user selects the separation time as 2 hours then I will need to keep the rows even with all zero values if that row is within 2 hours from a non-zero row above it.
The result whould look like this:
2001 08 25 15 25 0.00 0.00
2001 08 25 15 30 0.00 0.10
2001 08 25 15 35 0.15 0.00
2001 08 25 15 40 0.30 0.00
2001 08 25 15 45 0.20 0.00
2001 08 25 15 50 0.10 0.00
2001 08 25 15 55 0.00 0.00
2001 08 25 16 00 0.00 0.00
2001 08 25 16 05 0.00 0.90
2001 08 25 16 10 0.00 0.00
这是我读取数据的方式:
Here is how I am reading the data:
//Read Year Month, Day Hour and Minute and store them as date in an array
DateTime[] dt = new DateTime[this.dataGridView1.Rows.Count-1];
DataTable gageValues = new DataTable();
int i = 0;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells[0].Value != null)
String mth = row.Cells[1].Value.ToString() + "/";
String dy = row.Cells[2].Value.ToString() + " ";
String hr = row.Cells[3].Value.ToString() + ":";
String min = row.Cells[4].Value.ToString();
if (mth.Length == 1)
{
mth = "0" + mth;
}
if (dy.Length == 1)
{
dy = "0" + dy;
}
if (hr.Length == 1)
{
hr = "0" + hr;
}
if (min.Length == 1)
{
min = "0" + min;
}
string dts = yr + mth + dy + hr + min;
dt[i] = Convert.ToDateTime(dts);
i++;
}
}
// Add the raingage values to the datatable-gageValues
this._dataArray.Clear();
for(int jj=5; jj<ngag+5; jj++)
{
_dataArray.Add(new double[this.dataGridView1.Rows.Count - 1]);
for(int ii=0;ii<this.dataGridView1.Rows.Count-1;ii++)
{
_dataArray[jj-5][ii]=double.Parse(this.dataGridView1.Rows[ii].Cells[jj].Value.ToString());
}
}
List<object> objectNumbers = new List<object>();
gageValues.Columns.Add("DateTime");
foreach (DateTime dttm in dt)
{
objectNumbers.Add((object)dttm);
gageValues.Rows.Add();
for (int a = 0; a < objectNumbers.Count - 5; a++)
{
gageValues.Rows[a][0] = objectNumbers[a];
}
}
objectNumbers.Clear();
for (int ii = 0; ii < this._dataArray.Count; ii++)
{
string gageNames = this._names[ii];
gageValues.Columns.Add(gageNames);
foreach (double number in this._dataArray[ii])
{
objectNumbers.Add((object)number);
}
while (gageValues.Rows.Count < objectNumbers.Count)
{
gageValues.Rows.Add();
}
for (int a = 0; a < objectNumbers.Count; a++)
{
gageValues.Rows[a][ii+1] = objectNumbers[a];
}
objectNumbers.Clear();
}
然后我在每一行中添加值以检查总和是否为零,这有助于我找出哪些行全为零
Then I add values in each row to check if the sum is zero which helps me figure out which rows have all zeros
double[] sumrow = new double[gageValues.Rows.Count];
int count = -1;
foreach (DataRow dr in gageValues.Rows)
{
count = count + 1;
double sum = 0;
for(int j=1; j<gageValues.Columns.Count;j++)
{
sum = double.Parse(dr[j].ToString()) + sum;
}
sumrow[count] = sum;
}
现在,我尝试分析此sumrow []数组以隔离数据的非零块,但无法找出更好的逻辑.我们将不胜感激.
Now I am trying to analyze this sumrow[] array to isolate the non-zero blocks of the data but could not figure out a better logic. Any help will be greatly appreciated.
推荐答案
SA可能是正确的,尽管我希望首先更详细地了解您的数据.
我还建议其中一些是非常非常不必要的:
SA may be right, though I would want to see your data in more detail first.
I would also suggest that some of this is very, very unnecessary:
String mth = row.Cells[1].Value.ToString() + "/";
String dy = row.Cells[2].Value.ToString() + " ";
String hr = row.Cells[3].Value.ToString() + ":";
String min = row.Cells[4].Value.ToString();
if (mth.Length == 1)
{
mth = "0" + mth;
}
if (dy.Length == 1)
{
dy = "0" + dy;
}
if (hr.Length == 1)
{
hr = "0" + hr;
}
if (min.Length == 1)
{
min = "0" + min;
}
string dts = yr + mth + dy + hr + min;
dt[i] = Convert.ToDateTime(dts);
可以替换为:
Could be replaced with:
dt[i] = new DateTime(yr,
row.Cells[1].Value, //Month
row.Cells[2].Value, //Day
row.Cells[3].Value, //Hour
row.Cells[4].Value);//Minute
我认为您需要查看如何处理所有这一切:我特别不喜欢代码中混有+5和-5-我知道您这样做的原因,但是很难理解和维护. br/>
不要使用List<object>
-具体来说,它有助于避免出现问题,这意味着您无需先投射它就可以使用它!
老实说,我将使用一个采用DataGridViewRow的构造函数和一个ContainsInformaion属性getter来设置一个类(称为DatedValues)来保存行数据.如果为true,则将添加该行,否则将其丢弃.该类将具有(例如)一个DateTime属性和一个值列表.然后使用带信息的DatedValues列表代替您的List<Object>
-这将使您的代码更加清晰!
"感谢OriginalGriff的回复.
设置课程听起来是一种更好的方法.我最初计划只包含一个值列,然后以这种方式开始,但后来决定添加更多的值列.
我仍然无法弄清楚如何隔离数据中的非零块.对我而言,最难的部分是照顾两个非零块之间的最小间隔.我可以将原始数据,目标结果和规则发送给您...但是我找不到在此处附加任何文件的方法"
您的从非零开始的两个小时"状态应该不会成为太大的问题:将日志时间作为DateTime后,您可以使用DateTime.AddHours或DateTime.AddMinutes方法.请记住,您可以在两个DateTime对象之间进行直接比较:
I think you need to look at how you are handling all this: I particularly dislike the +5 and -5 your code is sprinkled with - I know why you are doing it, but it is hard to understand and maintain.
Don''t use List<object>
- be specific, it helps to avoid problems and means you don''t have to cast it before you can use it!
To be honest, I would set up a class (call it DatedValues)to hold row data with a constructor taking a DataGridViewRow and with a ContainsInformaion property getter. If true, I would add the row, otherwise I would discard it. The class would have (say) a DateTime property, and a List of values. Then use a list of the with-information DatedValues instead of your List<Object>
- it will make your code a lot clearer!
"Thanks OriginalGriff for your response.
Setting up a class sounds like a better way to do this. I initially planned on having only one value column and started this way but later decided to add more value columns.
I still cannot figure out how I isolate the non-zero blocks in my data. The hardest part for me is to take care of minimum separation between two non-zero blocks. I can send you my original data, targetted result and the rules... but I could not find a way to attach any file here"
Your "two hours since a non-zero" condition shouldn''t be too major a problem: once you have the log time as a DateTime, you can set a "always include if before this" DateTime by using the DateTime.AddHours or DateTime.AddMinutes methods. Remember, you can do direct comparisons between two DateTime objects:
DateTime now = DateTime.Now;
DateTime then = now.AddMinutes(120);
...
if (myRecord.Timestamp <= then)
{
...
}
我有一种强烈的感觉,您认为零数据不应该为零.您是否尝试过读取零以表示无效数据或无数据"?那是错误的.例如,您应该使用double.NaN
的值.
—SA
I have a strong feeling that you zero data is not supposed to be zero. Did you try to read zeroes to denote invalid data or "no data"? That would be wrong. You should use, for example, the values ofdouble.NaN
.
—SA
这篇关于寻找更智能的方式读取和写入时间序列数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!