用于处理大型.csv文件的程序架构
18次浏览(过去30天)
显示旧的注释
下午好
所以我有点担心。我刚刚花了一周的时间写了一个matlab程序,它从一个.csv文件中接收大量数据
当我开始项目时,我选择了一个表变量类型,因为它易于使用的函数,如readtable()
然而,我并没有被一个不可用的程序所困。matlab要花几个小时来处理我的。csv文件
我考虑了以下几种选择
matlab似乎还没有为表数据类型开发出任何性能,而且希望渺茫。
1:用数组重写整个程序
问题是,我文件中的数据都是十六进制值。我需要使用hex2dec函数将它们转换为十进制数字,该函数只适用于char数据类型。因此,使用双精度数组是不可能的。不知道该去哪里
2:尝试用paraelle工具箱重写程序
想法吗?
回答(5)
彼得·珀金斯
2021年7月28日
编辑:彼得·珀金斯
2021年7月28日
因为没有代码,所以很难给出具体的建议。
撇开十六进制问题不谈,我给出的第一个建议是编写向量化代码。事实上,您有50k次下标调用,这表明您正在一个紧密循环中执行标量操作。这不是用MATLAB写代码的最好方法。同样,没有太多的信息,所以很难说。这么多对大括号下标的调用表明您正在使用大括号对一个变量进行赋值,正如Walter指出的那样,这比使用dot要慢(因为它通常要做更多的事情)。这是一个不幸的差异,在文档中没有强调,但也许应该强调。无论如何,没有代码可以继续,所以…
Walter是正确的,自18b以来,性能,特别是对大表的分配,已经有了相当大的改进。
如果不能向量化,也不能升级到新版本,可能就没有必要“使用数组重写整个程序”。通常可以只关注紧循环,并为这部分代码从表中“提升”出一些变量,然后再将它们放回去。使用表格提供组织和方便,使用原始数字在小剂量的性能。表有很多事情要做,并且永远不会像双数组那样快。这并不意味着你应该避开它们。
提供具体的代码示例确实很有帮助。
沃尔特·罗伯森
2021年7月27日
在
一些
根据文件的格式,你有一些如何继续的选项:
- readtable()和readmatrix()和readcell()都允许使用'Format'选项,使用与textscan()相同的格式规范——包括使用%x格式的可能性(如果您的字段是固定宽度,则可能使用长度规范)。
- 您可以直接使用textscan(),因为您正在处理文本文件
- 你可以使用更低级的I/O命令,包括fscanf()或fgetl()和sscanf(),这取决于你的文件有多复杂。如果您的格式足够复杂,实际上需要一次读取一行,那么这可能会降低性能
- 当您的文件不是超级复杂,但确实有不同的部分时,通过将整个文件作为文本读取并使用regexp()将其分解为子部分,然后使用textscan()或sscanf()子部分,可以获得令人惊讶的高性能。也就是说,相对于循环测试每一行的性能增益。
杰里米·休斯
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
2021年7月31日
如果我能把它提前作为十六进制值,我会在更好的形状。你们谁能提个建议吗?”
上面沃尔特已经做过了。
注:
readXXX
新形式的
readmatrix
所有的重担都交给了
readtable
最后;其他的只是前端,让它知道文件的内容是什么,并指定如何将数据返回给调用者。
这些可能会提供一个小的性能提升超过可读;它们通常会返回一个数组或单元格数组,而不是一个表。如果所有操作都基于数组,那么使用表可能没有任何优势。
然而,使用
detectImportOptions
自定义一个导入对象,包括变量类型为十六进制,几乎肯定会带来好处——主要的一个是将数据导入为十进制值,而不是'char'或cellstr或字符串,然后必须进行转换——相反,将工作传递给系统I / O库。