我一直在做一个项目,我必须尽快读取和处理数百万行的非常大的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
读取文件后进行进一步处理?
我还很好奇,与上面链接中显示的其他方法相比,如何在pandas中读取文件的速度更快?
os.system
完全放弃了你在Python中的控制权。完成后无法访问子进程中发生的任何事情。
对子进程进行一些(但不充分)控制的更好方法是使用Python subprocess
模块。这允许您使用信号和I / O与正在运行的进程进行交互,但是,除非它具有允许您执行此操作的特定API,否则无法影响进程的内部。 (如果你想探索它,Linux会在/proc
文件系统中公开一些进程内部。)
我不认为您理解基准意味着什么。 cat >/dev/null
是一个基线,可以简单地测量系统从磁盘读取文件的速度;您的进程可能不会比I / O通道允许的更快,因此这是系统根本不采取任何操作所需的时间。在比较它们的相对性能之前,您基本上会从后续结果中减去此时间。
传统上,读取大文件的绝对最快的方法是索引它,然后使用内存中的索引来搜索要访问的文件内的位置。构建索引会导致一些开销,但如果您不止一次访问该文件,这些好处很快就会消除开销。将文件导入数据库是一种方便友好的方法;数据库完全封装了I / O,并允许您查询数据,就好像您可以忽略它在某些方面被序列化为磁盘后面的字节。
根据我的测试。我发现在pandas数据框中查询比在数据库中查询要快得多[为sqlite3测试]
因此,最快的方法是将csv作为pandas数据帧,然后根据需要在数据帧中进行查询。此外,如果我需要保存文件,我可以挑选数据帧,并根据需要重用它。 pickle和unpickle文件和查询的时间比在sql中存储数据然后查询结果要少得多。