绘制大量数据

问题描述 投票:16回答:4

我们目前正在使用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上。

c# .net charts large-files zedgraph
4个回答
8
投票

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

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

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

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

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


4
投票

我将通过两个步骤来解决这个问题:

  1. 预处理数据
  2. 显示数据

步骤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.规范化数据并创建具有开,高,低,接近值的聚合数据条。一个。按时间b。按记录计数c。通过Diff之间的值

有关聚合非统一数据集的更多可能方法,您可能需要查看用于汇总金融市场中交易数据的不同方法。当然,为了实时渲染速度,您需要创建已经聚合了这些数据的文件。


3
投票

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

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

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

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

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


1
投票

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

  1. 在小点分组中迭代数据(一次说3到5个点 - 组越大,算法运行得越快,但聚合的准确性越低)。
  2. 计算小组的最小值和最大值。
  3. 从该组中删除所有不是最小值或最大值的点(即,每组只保留2个点并省略其余点)。
  4. 保持循环遍历数据(重复此过程)从开始到结束删除点,直到聚合数据集具有足够少的点数,其中可以绘制图表而不会阻塞PC。

过去我曾使用过这种算法,将约1000万点的数据集下降到~5K点的数量级,图形没有任何明显的可见失真。

这里的想法是,在抛出点时,你会保留峰值和谷值,因此在最终图表中查看的“信号”不会“平均下降”(通常,如果平均,你会看到峰值和山谷变得不那么突出了)。

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.