用于处理大型.csv文件的程序架构

18次浏览(过去30天)
罗伯特·斯科特
罗伯特·斯科特 2021年7月27日
评论道: Rena伯曼 2021年9月23日
下午好
所以我有点担心。我刚刚花了一周的时间写了一个matlab程序,它从一个.csv文件中接收大量数据
当我开始项目时,我选择了一个表变量类型,因为它易于使用的函数,如readtable()
然而,我并没有被一个不可用的程序所困。matlab要花几个小时来处理我的。csv文件
我考虑了以下几种选择
matlab似乎还没有为表数据类型开发出任何性能,而且希望渺茫。
1:用数组重写整个程序
问题是,我文件中的数据都是十六进制值。我需要使用hex2dec函数将它们转换为十进制数字,该函数只适用于char数据类型。因此,使用双精度数组是不可能的。不知道该去哪里
2:尝试用paraelle工具箱重写程序
想法吗?

回答(5)

彼得·珀金斯
彼得·珀金斯 2021年7月28日
编辑:彼得·珀金斯 2021年7月28日
因为没有代码,所以很难给出具体的建议。
撇开十六进制问题不谈,我给出的第一个建议是编写向量化代码。事实上,您有50k次下标调用,这表明您正在一个紧密循环中执行标量操作。这不是用MATLAB写代码的最好方法。同样,没有太多的信息,所以很难说。这么多对大括号下标的调用表明您正在使用大括号对一个变量进行赋值,正如Walter指出的那样,这比使用dot要慢(因为它通常要做更多的事情)。这是一个不幸的差异,在文档中没有强调,但也许应该强调。无论如何,没有代码可以继续,所以…
Walter是正确的,自18b以来,性能,特别是对大表的分配,已经有了相当大的改进。
如果不能向量化,也不能升级到新版本,可能就没有必要“使用数组重写整个程序”。通常可以只关注紧循环,并为这部分代码从表中“提升”出一些变量,然后再将它们放回去。使用表格提供组织和方便,使用原始数字在小剂量的性能。表有很多事情要做,并且永远不会像双数组那样快。这并不意味着你应该避开它们。
提供具体的代码示例确实很有帮助。
3评论
沃尔特·罗伯森
沃尔特·罗伯森 2021年7月28日
如果不了解需要执行的各种操作,就很难讨论高级程序架构。
例如,有 一些 对于这种需求,最有效的方法是使用字符的多维超立方体,将任何一个“单词”的文本存储为 (而不是典型的行。)但是,您可能希望将“单词”存储为其他需要 在超立方体中。

登录评论。


沃尔特·罗伯森
沃尔特·罗伯森 2021年7月27日
一些 根据文件的格式,你有一些如何继续的选项:
  • readtable()和readmatrix()和readcell()都允许使用'Format'选项,使用与textscan()相同的格式规范——包括使用%x格式的可能性(如果您的字段是固定宽度,则可能使用长度规范)。
  • 您可以直接使用textscan(),因为您正在处理文本文件
  • 你可以使用更低级的I/O命令,包括fscanf()或fgetl()和sscanf(),这取决于你的文件有多复杂。如果您的格式足够复杂,实际上需要一次读取一行,那么这可能会降低性能
  • 当您的文件不是超级复杂,但确实有不同的部分时,通过将整个文件作为文本读取并使用regexp()将其分解为子部分,然后使用textscan()或sscanf()子部分,可以获得令人惊讶的高性能。也就是说,相对于循环测试每一行的性能增益。
4评论
罗伯特·斯科特
罗伯特·斯科特 2021年7月28日
谢谢你的意见。可以试试吗

登录评论。


杰里米·休斯
杰里米·休斯 2021年7月28日
编辑:杰里米·休斯 2021年7月29日
首先,查看示例文件和一些演示问题的示例代码会有所帮助。
这是我所看到的最好的说法。
如果整个变量是十六进制格式,您可以使用导入选项在导入时快速进行转换。
detectImportOptions 将会看到 0 x1a 作为十六进制值,但不是没有前缀,但如果你要求它,它可以被读取为十六进制。
opts = detectImportOptions(文件名,“分隔符”","
% varNamesOrNumbers = [1 3 5]
% or varNamesOrNumbers = ["Var1","Var3"]
opts = setvaropts(opts, varNamesOrNumbers,“NumberSystem”“六角”“类型”“汽车”);
您也可以通过只选择列来提高读取性能
%你想要(这是可选的)
选择。SelectedVariableNames =选项。VariableNames([1 3 5 7 9]);
T = readtable(文件名,opts)
12个评论
dpb
dpb 2021年7月31日
如果我能把它提前作为十六进制值,我会在更好的形状。你们谁能提个建议吗?”
上面沃尔特已经做过了。
注: readXXX 新形式的 readmatrix 所有的重担都交给了 readtable 最后;其他的只是前端,让它知道文件的内容是什么,并指定如何将数据返回给调用者。
这些可能会提供一个小的性能提升超过可读;它们通常会返回一个数组或单元格数组,而不是一个表。如果所有操作都基于数组,那么使用表可能没有任何优势。
然而,使用 detectImportOptions 自定义一个导入对象,包括变量类型为十六进制,几乎肯定会带来好处——主要的一个是将数据导入为十进制值,而不是'char'或cellstr或字符串,然后必须进行转换——相反,将工作传递给系统I / O库。

登录评论。


罗伯特·斯科特
罗伯特·斯科特 2021年8月3日
我想回到这个问题上。
所以我在这个项目上投入了大量的时间,我想感谢每一个参与进来的人。
我已经找到了自己的答案,我真的很惊讶没有人提到这一点,我可以看到。
答案是,你不能!!你不能阅读大文件。matlab将这些文件带入ram的方式有很多开销。我用书中的每一个技巧重写了我的程序,从我的rev 1开始,我的速度提高了近1000倍!你猜怎么着!还是不够好。当我开始要求我的程序用各种各样的技巧,向量化,parfor循环等来运行一个10k行的文件时,我得到了惊人的速度。500美元一行!太棒了。猜猜当你读取一个有500k行的文件时会发生什么,我的500us现在是500mS。 The answer is you just cant. You cant bring in all the data locally and not impact performance. You need to read it one line at a time OUTSIDE of matlab so matlab doesnt slow down.
这就是答案,这是这篇文章的重点。答案是使用 放开,放开 .Fgets相当快。
在解析文件时逐行读取文件。这是唯一的办法。这也可以防止你的内存填满。
我希望我的痛苦和折磨可以帮助别人在未来。甚至不用担心高数组和数据存储。所有这些东西都有很多开销,解决方案实际上是你的死亡。
打开,打开,一行一行地读。fgets在美国规模上执行,永远不会被ram减慢。
这十天对我来说真是浪费。感谢所有支持这次学习实验的人。
3评论
dpb
dpb 2021年8月3日
“…每一行由重复的4个十六进制数字组成,代表有符号的16位数字……” @Walter罗伯森
我最终得到了一个响应,除了每个记录的第一个和最后一个元素外,每个记录都是十六进制,但从未回应这两个是什么。由于拒绝提供任何进一步有用的细节,所有其他细节仍然不透明。

登录评论。


罗伯特·斯科特
罗伯特·斯科特 2021年8月3日
这个案子已经结案了。我已经感谢了你们所有人的帮助,我不能再分享或讨论这一点了。我已经说过很多次了,我不能分享任何东西,除了一般的matlab原理和讨论matlab本身是如何工作的。我已经找到了一个合适的解决方案使用fgets。大家好。

标签

2022世界杯八强谁会赢?


释放

R2018b

世界杯预选赛小组名单社区寻宝

在MATLAB Central中找到宝藏,并发现社区如何帮助您!世界杯预选赛小组名单

开始狩猎!

Baidu
map