我一直在从事一个项目,在该项目中,我必须尽可能快地读取和处理具有数百万行的超大型csv文件。
我碰到了链接:https://nelsonslog.wordpress.com/2015/02/26/python-csv-benchmarks/,作者在其中对访问csv的不同方法和每个步骤所花费的时间进行了基准测试。 他使用了一个catdevnull进程,其代码如下所示:
def catDevNull():
os.system('cat %s > /dev/null' % fn)
在这种情况下花费的时间最少。我相信它独立于python版本,因为读取文件所需的时间保持不变。然后,他使用了如下所示的温热疼痛方法:
def wc():
os.system('wc -l %s > /dev/null' % fn)
以上两种方法最快。使用pandas.read_csv
来完成任务,时间比其他方法要少,但仍比上述两种方法慢。
放入x = os.system('cat %s > /dev/null % fn)
,然后检查数据类型是否为字符串。
os.system
如何读取时间短得多的文件?另外,os.system
读取文件后,是否可以访问文件进行进一步处理?
我也很好奇,与上面链接中显示的其他可用方法相比,在熊猫中读取文件的速度如何如此之快?
答案 0 :(得分:3)
os.system
完全放弃了您在Python中拥有的控件。完成子流程后,无法访问子流程中的任何内容。
对子进程进行某些(但不充分)控制的更好方法是使用Python subprocess
模块。这使您可以使用信号和I / O与正在运行的进程进行交互,但是,除非它具有允许您执行此操作的特定API,否则仍然无法影响进程的内部。 (如果您想探索,Linux在/proc
文件系统中公开了一些过程内部信息。)
我认为您不了解基准测试的含义。 cat >/dev/null
是一个基准,仅用于衡量系统能够从磁盘读取文件的速度。您的过程可能不会快于I / O通道允许的速度,因此这是系统完全不执行任何操作所花费的时间。在比较它们的相对性能之前,您基本上应该从随后的结果中减去这次的时间。
按惯例,读取大文件的绝对最快的方法是对其进行索引,然后使用内存中的索引查找要访问的文件内的位置。建立索引会产生一些开销,但是如果您多次访问文件,那么好处很快就会消除开销。将文件导入数据库是一种方便而友好的方式。数据库将I / O完全封装起来,让您查询数据,就好像您可以忽略它以某种方式序列化到幕后磁盘上的字节一样。
答案 1 :(得分:0)
根据我的测试。我碰到一个事实,在熊猫数据框中查询比在数据库中查询要快得多(已测试sqlite3)
因此,最快的方法是将csv作为pandas数据框获取,然后根据需要在数据框中查询。另外,如果需要保存文件,则可以对数据框进行腌制,然后根据需要重新使用它。腌制和解开文件以及查询的时间比将数据存储在sql中然后查询结果要少得多。