python 加速csv读取速度_与Python相比,在Julia中读取csv速度较慢

与Python相比,在Julia中读取大型文本/ csv文件需要花费很长时间。 这是读取大小为486.6 MB,具有153895行和644列的文件的时间。

python 3.3示例

import pandas as pd

import time

start=time.time()

myData=pd.read_csv("C:\\myFile.txt",sep="|",header=None,low_memory=False)

print(time.time()-start)

Output: 19.90

R 3.0.2示例

system.time(myData

stringsAsFactors=F,na.strings=""))

Output:

User    System  Elapsed

181.13  1.07    182.32

朱莉娅0.2.0(Julia Studio 0.4.4)示例#1

using DataFrames

timing = @time myData = readtable("C:/myFile.txt",separator='|',header=false)

Output:

elapsed time: 80.35 seconds (10319624244 bytes allocated)

朱莉娅0.2.0(Julia Studio 0.4.4)示例#2

timing = @time myData = readdlm("C:/myFile.txt",'|',header=false)

Output:

elapsed time: 65.96 seconds (9087413564 bytes allocated)

Julia比R更快,但与Python相比却相当慢。 我可以采取什么其他措施来加快读取大文本文件的速度?

一个单独的问题是内存的大小是Julia文件中硬盘文件大小的18倍,而python则只有2.5倍。 在Matlab中,我发现大型文件的内存使用效率最高,它是硬盘文件大小的2倍。 茱莉亚(Julia)内存中的大文件大小有任何特殊原因吗?

顺便说一句,在R中,我建议使用data.table包中的fread,它的速度要快得多。

@baptiste,无法获取fread来读取文件。 给我一个错误Expected sep (|) but" ends field 412 on line 12141 when reading data: ...。 字段412的字符串中有两个",而fread对此有问题。 同样,以其读取到第12141行的速度,假设总时间为36.1秒-因此可能比read.delim有了显着改善。

最好的答案可能是我不像Wes那样优秀。

通常,DataFrames中的代码比Pandas中的代码优化程度差得多。我相信我们可以赶上,但是这需要一些时间,因为首先需要实现许多基本功能。由于在Julia中需要构建的内容太多,因此我倾向于将工作分为三个部分:(1)构建任何版本,(2)构建正确的版本,(3)构建快速正确的版本。对于我所做的工作,Julia通常不提供任何版本的基本功能,因此我的工作重点是(1)和(2)。随着我需要构建更多的工具,专注于性能将变得更加容易。

至于内存的使用,我认为答案是我们在解析表格数据时使用了一组数据结构,而这些数据结构的效率要比熊猫所使用的效率低得多。如果我更好地了解了Pandas的内部,我可以列出一些效率较低的地方,但是现在我只能推测一个明显的失败是我们正在将整个数据集读取到内存中,而不是从磁盘上抓取块。当然可以避免这种情况,这样做存在很多问题。这只是时间问题。

关于这一点,readtable代码非常易于阅读。使readtable更快的最确定的方法是鞭打Julia探查器并开始修复它发现的性能缺陷。

谢谢,约翰。 保持良好的工作。 我一定会继续监视朱莉娅

我发现了一些可以部分帮助这种情况的东西。

在Julia中使用readdlm()函数似乎比readtable()快得多(例如,在最近的试用中是3倍)。当然,如果要使用DataFrame对象类型,则需要将其转换为它,这可能会消耗大部分或全部速度改进。

指定文件的尺寸在速度和内存分配上都可以带来很大的不同。我运行了该试用版,并读取了磁盘上258.7 MB的文件:

julia> @time Data = readdlm("MyFile.txt", '\t', Float32, skipstart = 1);

19.072266 seconds (221.60 M allocations: 6.573 GB, 3.34% gc time)

julia> @time Data = readdlm("MyFile.txt", '\t', Float32, skipstart = 1, dims = (File_Lengths[1], 62));

10.309866 seconds (87 allocations: 528.331 MB, 0.03% gc time)

对象的类型说明非常重要。例如,如果您的数据中包含字符串,则您读入的数组的数据将为Any类型,这在内存方面是昂贵的。如果确实存在内存问题,则可能需要考虑先对数据进行预处理,方法是先将字符串转换为整数,然后进行计算,然后再转换回去。另外,如果您不需要很多精度,那么使用Float32类型而不是Float64可以节省很多空间。您可以在读取文件时指定此名称,例如:

Data = readdlm("file.csv", ',', Float32)

关于内存使用,我特别发现PooledDataArray类型(来自DataArrays包)有助于减少内存使用,如果您的数据包含很多重复值。转换为这种类型的时间相对较长,因此它本身并不是节省时间的方法,但至少可以帮助减少内存使用量。例如。当加载具有1900万行和36列的数据集时,其中8个代表分类变量以进行统计分析,这将对象的内存分配从磁盘上的大小的5倍减少到磁盘的4倍。如果还有更多重复的值,则内存减少的意义甚至更大(我曾经遇到过PooledDataArray将内存分配减少一半的情况)。

有时,在加载和格式化数据以清除所有不需要的ram分配之后,有时还可以帮助运行gc()(垃圾收集器)功能,尽管通常Julia会自动完成此操作。

尽管如此,尽管如此,我仍希望在Julia上进行进一步的开发,以便为大型数据集实现更快的加载和更有效的内存使用。

Jacob Quinn有一个相对较新的julia软件包CSV.jl,它提供了更快的CSV解析器,在许多情况下可与熊猫媲美:https://github.com/JuliaData/CSV.jl

请注意,从@time输出的"已分配n个字节"是所有已分配对象的总大小,而忽略了可能释放了多少个对象。此数字通常比内存中活动对象的最终大小高得多。我不知道这是您的内存大小估算值的依据,但是我想指出这一点。

以我的经验,处理较大文本文件的最佳方法不是将它们加载到Julia中,而是将其流化。 此方法有一些额外的固定成本,但通常运行非常快。 一些伪代码是这样的:

function streamdat()

mycsv=open("/path/to/text.csv","r")   #

sumvec = [0.0]                #

i = 1

while(!eof(mycsv))            #

row = readline(mycsv)

vector=split(row,"|")     #

sumvec+=parse(Float64, vector[i])

i+=1

end

end

streamdat()

上面的代码只是一个简单的总结,但是可以将此逻辑扩展为更复杂的问题。

朱莉娅(Julia)应该被构建为对用户透明地使用数据库,并且能够执行从该数据库流式传输的所有操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值