如果要进行行级数学运算,应将数据系列存储在文件还是数据库中?
我正在开发一个应用程序,用来处理一组金融数据(可以是csv文件或开放文档格式)。每一组数据可能包含成千上万的双精度数字(简单来说,就是这些数字很大)。
我计划对这些数据进行一些操作,比如求和、求差、计算平均值等等,还想根据输入的数据生成另一列。这些操作会在同一组数据的列之间进行,也可能在多组(甚至所有)数据的列之间进行。我的计划是用Python来实现,最终需要一个内网界面来展示结果和图表,目前先用csv格式输出一些参数的结果就可以了。
那么,存储和处理这些数据的最佳方式是什么呢?目前我有两个选择:一是把csv文件写到磁盘上,然后逐个读取进行计算;二是把数据放到数据库里,让数据库来处理这些计算。我的主要担心是,随着数据集的增多,速度和性能会受到影响,因为需要进行跨数据集的行级计算。
- 有没有人有过这两种方法的经验?我应该注意哪些陷阱或问题?
- 为什么选择一种方法而不是另一种?
- 在开始之前,有没有什么潜在的速度或性能问题/提升需要我注意的,这可能会影响设计?
- 有没有什么项目或框架可以帮助我完成这种任务?
-补充- 更多信息: 所有的行会按顺序读取,但我可能需要进行一些重采样或插值,以匹配不同输入长度和每行不同时间戳。由于每个数据集的长度都不固定,我会在某个地方有一个临时表或内存来存放插值或重采样后的版本。我不确定是把这些存储起来(并尝试上采样或插值到一个共同的更高长度),还是每次需要时重新生成它们更合理。
4 个回答
你是需要按顺序获取所有的行,还是只想要一些特定的已知行呢?
如果你需要读取所有的数据,把它放在数据库里其实没什么太大好处。
补充一下:如果代码可以放进内存里,那么用简单的CSV文件就可以了。普通的文本数据格式总是比那些复杂的格式更容易处理,如果你能使用它们的话。
为了提高速度,我建议你可以考虑两个方向,除了改变你的存储方式之外:
1) 使用中间数据结构。
如果你觉得速度更重要,而不是内存使用量,那么可以尝试用不同的数据结构来进行计算,而不是只关注底层的存储方式。这种方法在我参与的项目中,确实大幅度减少了运行时间,无论数据是存储在数据库里还是文本文件中(在我的例子里是XML)。
简单的求和和平均值计算只需要的时间是 O(n),但如果计算比较复杂,可能会变成 O(n^2),而不使用这种策略的话,性能就会大打折扣。O(n^2) 的计算速度会比你是从CSV文件还是数据库读取数据的影响要大得多。比如说,如果你的数据行之间有相互引用的关系,需要根据这些引用来汇总数据。
所以,如果你发现自己在做比求和或平均值更复杂的计算,可以考虑使用在 O(n) 时间内创建的数据结构,这样你的计算操作也能保持在 O(n) 或更好的水平。正如马丁提到的,听起来你的整个数据集都可以轻松放在内存中,这样可能会带来很大的提升。你创建什么样的数据结构,取决于你要进行的计算类型。
2) 预缓存。
根据数据的使用方式,你可以提前存储计算好的值。数据一旦生成或加载,就立即进行求和、求平均等操作,并把这些结果和原始数据一起存储,或者在程序运行期间一直保存在内存中。如果这个策略适合你的项目(也就是说,用户不会随时提出意想不到的计算请求),那么读取数据的时间就不会太长,无论数据来自文本文件还是数据库。
“我打算对这些数据进行一些操作(比如求和、求差、计算平均值等),还包括根据输入数据的计算生成另一列。”
这就是数据仓库星型架构设计的标准用法。建议你买一本Kimball的《数据仓库工具箱》。在做其他事情之前,先读懂星型架构。
“存储数据和处理数据的最佳方式是什么?”
使用星型架构。
你可以把数据存成平面文件(CSV格式就可以)或者使用关系数据库管理系统(RDBMS)。如果用平面文件,你可以写简单的循环来进行计算。如果用RDBMS,你需要写简单的SQL语句和简单的循环。
“我最关心的是随着数据集的增加,速度和性能。”
没有什么比平面文件更快了。就是这样。RDBMS会慢一些。
RDBMS的优势在于,SQL是一种相对简单的方式来指定SELECT SUM(), COUNT() FROM fact JOIN dimension WHERE filter GROUP BY dimension attribute
。虽然Python没有SQL那么简洁,但它同样快速且灵活。Python和SQL是可以相互竞争的。
“我应该注意哪些陷阱或问题?”
数据库设计。如果你不理解星型架构以及如何将事实和维度分开,所有的方法都会失败。一旦你把事实和维度分开,所有的方法大致上都是相等的。
“为什么要选择一种方法而不是另一种?”
RDBMS慢但灵活,平面文件快但(有时)灵活性差。Python让这两者的差距缩小了。
“在我开始之前,有没有潜在的速度或性能问题/提升需要注意的,这可能会影响设计?”
星型架构:中心是事实表,周围是维度表。没有什么能比这个更好了。
“有没有什么项目或框架可以帮助完成这种任务?”
其实没有。