绘制大量数据

时间:2011-01-27 15:00:24

标签: c# .net charts large-files zedgraph

我们目前正在使用ZedGraph绘制一些数据的折线图。输入数据来自任意大小的文件,因此,我们事先不知道数据点的最大数量是多少。但是,通过打开文件并读取标题,我们可以找出文件中有多少数据点。

文件格式基本上是[时间(双倍),值(双精度)]。但是,条目在时间轴上不一致。在说t = 0秒和t = 10秒之间可能没有任何分数,但在t = 10秒和t = 11秒之间可能有100K的时间,依此类推。

例如,我们的测试数据集文件大约是2.6 GB,它有324M点。我们想向用户展示整个图表,让她浏览图表。但是,向ZedGraph加载324M点不仅是不可能的(我们使用的是32位机器),但也没用,因为屏幕上没有这么多点。

使用ZedGraph的FilteredPointList功能似乎也是不可能的,因为这需要先加载整个数据,然后对该数据执行过滤。

所以,除非我们遗漏任何东西,否则我们唯一的解决办法似乎是 - 以某种方式对数据进行抽取,但是当我们不断努力时,我们遇到了很多问题:

1-我们如何抽取未及时到达的数据?

2-由于无法将整个数据加载到内存中,因此任何算法都需要在磁盘上运行,因此需要仔细设计。

3-我们如何处理放大和缩小,尤其是当数据在x轴上不均匀时。

如果数据是统一的,那么在初始加载图形时,我们可以通过文件中预定义的条目量Seek(),并选择每N个其他样本并将其提供给ZedGraph。但是,由于数据不统一,我们必须更加智能地选择要显示的样本,我们无法提出任何不必读取整个文件的智能算法。

我道歉,因为这个问题没有严格的特异性,但我希望我能解释一下我们问题的性质和范围。

我们使用的是Windows 32位,.NET 4.0。

4 个答案:

答案 0 :(得分:8)

我以前需要这个,这并不容易。由于这个要求,我最终编写了自己的图形组件。最后结果更好,因为我提供了我们需要的所有功能。

基本上你需要得到数据范围(最小和最大可能/需要的索引值),细分为段(比如说100个段),然后通过某种算法确定每个段的值(平均值,中值)等)。然后根据总结的100个元素进行绘图。这比试图绘制数百万点要快得多: - )。

所以我所说的与你所说的相似。你提到你不想绘制每个X元素,因为元素之间可能存在很长的时间(x轴上的索引值)。我所说的是,对于每个数据细分,确定什么是最佳值,并将其作为数据点。我的方法是基于索引值的,所以在你的0秒和10秒索引值之间没有数据的例子中,我仍然将数据点放在那里,它们之间只有相同的值。

重点是在绘制数据之前对数据进行总结。仔细考虑您的算法,有很多方法可以做到这一点,选择适合您应用的算法。

您可能不会编写自己的图形组件而只是编写数据摘要算法。

答案 1 :(得分:4)

我会分两步来处理这个问题:

  1. 预处理数据
  2. 显示数据
  3. 第1步 该文件应预处理为二进制固定格式文件。 为格式添加索引,它将是int,double,double。 请参阅此文章以进行速度比较:

    http://www.codeproject.com/KB/files/fastbinaryfileinput.aspx

    然后,您可以将文件分解为时间间隔 每小时或每天一个,这将给你一个简单的表达方式 访问不同的时间间隔。你也可以保持 一个大文件,并有一个索引文件,告诉你在哪里找到特定的时间,

    1,1 / 27/2011 8:30:00
    13456,1 / 27/2011 9:30:00

    通过使用这些方法之一,您将能够快速找到任何数据块 由于固定字节,由时间,通过索引或文件名,或由条目数 格式。

    第2步 显示数据的方法 1.只需按索引显示每条记录。 2.规范化数据并创建具有开,高,低,接近值的聚合数据条。     一个。按时间     湾按记录计数     C。通过值之间的差异

    有关聚合非统一数据集的更多可能方法,您可能需要查看 用于汇总金融市场贸易数据的不同方法。当然, 对于实时渲染的速度,您可能希望使用此数据创建文件 聚合

答案 2 :(得分:3)

  

1-我们如何抽取非数据   及时到达?

注意 - 我假设你的加载器数据文件是文本格式。)

在类似的项目中,我不得不阅读大小超过5GB的数据文件。我可以解析它的唯一方法是将其读入RDBMS表。我们之所以选择MySQL,是因为它将文本文件导入到数据表中简单易用。 (有趣的是 - 我在一台32位的Windows机器上无法打开文本文件进行查看,但MySQL没有看到它。)另一个特权是MySQL 尖叫,快速尖叫

一旦数据在数据库中,我们就可以轻松地对其进行排序并将大量数据量化为单个释义查询(使用内置的SQL汇总函数,如SUM)。 MySQL甚至可以将其查询结果读回文本文件,以用作加载器数据。

长话短说,消耗大量数据要求使用可以汇总数据的工具。 MySQL适合该法案(双关语意图......它是免费的)。

答案 3 :(得分:1)

我发现这样做的一个相对简单的替代方法是执行以下操作:

  1. 在小点分组中迭代数据(一次说3到5个点 - 组越大,算法运行得越快,但聚合的准确度就越低)。
  2. 计算min&最大的小组。
  3. 从该组中移除最小值或最大值的所有点(即每组只保留2个点并省略其余点)。
  4. 保持循环遍历数据(重复此过程)从开始到结束删除点,直到聚合数据集具有足够少的点数,可以在不阻塞PC的情况下绘制图表。
  5. 过去我曾使用过这个算法,将约1000万点的数据集下降到~5K点的数量级,图形没有任何明显的可见失真。

    这里的想法是,在抛出分数时,你要保留峰值和谷值,以便"信号"在最终图表中查看并未排除"#34; (通常情况下,如果平均,你会看到峰值和山谷变得不那么突出)。

    另一个好处是,你总能看到"真实的"最终图表上的数据点(它缺少一堆点,但实际上在原始数据集中的点,所以,如果你鼠标悬停在某些东西上,你可以显示实际的x& y值,因为它们&# 39;真实,不平均)。

    最后,这也有助于解决不具有一致x轴间距的问题(同样,您将拥有实际点而不是平均X轴位置)。

    我不确定这种方法在您拥有的数百万数据点中的效果如何,但它可能值得一试。