与Python相比,在Julia中读取csv的速度较慢
与Python相比,在Julia中读取大型文本/csv文件需要很长时间。下面是读取大小为486.6 MB、包含153895行和644列的文件的时间 Python3.3示例与Python相比,在Julia中读取csv的速度较慢,julia,Julia,与Python相比,在Julia中读取大型文本/csv文件需要很长时间。下面是读取大小为486.6 MB、包含153895行和644列的文件的时间 Python3.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
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
R3.0.2示例
system.time(myData<-read.delim("C:/myFile.txt",sep="|",header=F,
stringsAsFactors=F,na.strings=""))
Output:
User System Elapsed
181.13 1.07 182.32
Julia 0.2.0(Julia Studio 0.4.4)示例#2
最好的答案可能是我不像韦斯那样是一个好的程序员 一般来说,数据帧中的代码没有熊猫中的代码优化得好。我相信我们可以迎头赶上,但这需要一些时间,因为我们需要首先实现很多基本功能。由于Julia中需要构建的内容太多,因此我倾向于将重点放在三个部分:(1)构建任何版本,(2)构建正确的版本,(3)构建快速、正确的版本。对于我所做的工作,Julia通常不提供任何版本的基本功能,因此我的工作重点放在(1)和(2)。随着我需要的工具越来越多,关注性能将变得更加容易 至于内存使用,我认为答案是我们在解析表格数据时使用了一组数据结构,这比熊猫使用的效率要低得多。如果我能更好地了解Pandas的内部结构,我可以列出效率较低的地方,但现在我只能推测,一个明显的失败是我们将整个数据集读取到内存中,而不是从磁盘中获取数据块。这当然是可以避免的,而且存在这样做的问题。这只是时间问题
注意,
readtable
代码相当容易阅读。要使的可读性更快,最确定的方法是拿出Julia profiler并开始修复它所发现的性能缺陷。请注意,@time
的“n字节分配”输出是所有分配对象的总大小,忽略其中有多少可能已被释放。这个数字通常比内存中活动对象的最终大小高得多。我不知道这是否是您的内存大小估计的依据,但我想指出这一点。我发现了一些可以部分帮助这种情况的东西
在Julia中使用readdlm()
函数似乎比readtable()
快得多(例如,在最近的一次试验中是3倍)。当然,如果需要DataFrame对象类型,则需要将其转换为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”、“file.csv”、“Float32”)
关于内存使用,我特别发现,如果数据有很多重复值,PooledDataArray类型(来自DataArrays包)有助于减少内存使用。转换为这种类型的时间相对较长,因此这本身并不是一个节省时间的方法,但至少有助于在一定程度上减少内存使用。例如,加载包含1900万行和36列的数据集时,其中8列表示用于统计分析的分类变量,这将对象的内存分配从磁盘上的5倍大小减少到4倍大小。如果有更多的重复值,内存的减少可能会更加显著(我曾经遇到过PooledDataArray将内存分配减半的情况)
有时,在加载和格式化数据后运行gc()
(垃圾收集器)函数以清除任何不需要的ram分配也会有所帮助,尽管通常Julia会自动完成这项工作
尽管如此,尽管如此,我还是期待着Julia的进一步发展,以便能够更快地加载大型数据集并更有效地使用内存。根据我的经验,处理较大文本文件的最佳方法不是将其加载到Julia中,而是将其流式处理。这种方法有一些额外的固定成本,但通常运行速度非常快。以下是一些伪代码:
function streamdat()
mycsv=open("/path/to/text.csv", "r") # <-- opens a path to your text file
sumvec = [0.0] # <-- store a sum here
i = 1
while(!eof(mycsv)) # <-- loop through each line of the file
row = readline(mycsv)
vector=split(row, "|") # <-- split each line by |
sumvec+=parse(Float64, vector[i])
i+=1
end
end
streamdat()
函数streamdat()
MyCSV=打开(“/PATT/OT/TEX.CSV”,“R”)> Jacob Quinn有一个相对较新的朱丽亚包,称为CSV.JL,它提供了一个更快的CSV解析器,在许多情况下与大熊猫一致:
让我们首先创建一个您正在谈论的文件来提供可重复性:
open("myFile.txt", "w") do io
foreach(i -> println(io, join(i+1:i+644, '|')), 1:153895)
end
现在我在Julia 1.4.2和CSV.jl 0.7.1中阅读了这个文件
单螺纹:
julia> @time CSV.File("myFile.txt", delim='|', header=false);
4.747160 seconds (1.55 M allocations: 1.281 GiB, 4.29% gc time)
julia> @time CSV.File("myFile.txt", delim='|', header=false);
2.780213 seconds (13.72 k allocations: 1.206 GiB, 5.80% gc time)
julia> @time CSV.File("myFile.txt", delim='|', header=false);
1.898649 seconds (1.54 M allocations: 93.848 MiB, 1.48% gc time)
julia> @time CSV.File("myFile.txt", delim='|', header=false);
0.029965 seconds (248 allocations: 17.037 MiB)
并使用例如4个螺纹:
julia> @time CSV.File("myFile.txt", delim='|', header=false);
4.546945 seconds (6.02 M allocations: 1.499 GiB, 5.05% gc time)
julia> @time CSV.File("myFile.txt", delim='|', header=false);
0.812742 seconds (47.28 k allocations: 1.208 GiB)
在R中,它是:
> system.time(myData<-read.delim("myFile.txt",sep="|",header=F,
+ stringsAsFactors=F,na.strings=""))
user system elapsed
28.615 0.436 29.048
现在,如果我们从R(速度很快)测试fread
,我们得到:
因此,在这种情况下,总结如下:
- 尽管在Julia中编译
CSV.File
的成本很高,但在第一次运行它时,它比base R或Python快得多
- 它在速度上与R中的fread相当(在本例中稍微慢一点,但其他基准测试显示了它的情况)
> system.time(myData<-read.delim("myFile.txt",sep="|",header=F,
+ stringsAsFactors=F,na.strings=""))
user system elapsed
28.615 0.436 29.048
>>> import pandas as pd
>>> import time
>>> start=time.time()
>>> myData=pd.read_csv("myFile.txt",sep="|",header=None,low_memory=False)
>>> print(time.time()-start)
25.95710587501526
> system.time(fread("myFile.txt", sep="|", header=F,
stringsAsFactors=F, na.strings="", nThread=1))
user system elapsed
1.043 0.036 1.082
> system.time(fread("myFile.txt", sep="|", header=F,
stringsAsFactors=F, na.strings="", nThread=4))
user system elapsed
1.361 0.028 0.416
open("myFile.txt", "w") do io
foreach(i -> println(io, join(i+1:i+10, '|')), 1:100_000)
end
julia> @time CSV.File("myFile.txt", delim='|', header=false);
1.898649 seconds (1.54 M allocations: 93.848 MiB, 1.48% gc time)
julia> @time CSV.File("myFile.txt", delim='|', header=false);
0.029965 seconds (248 allocations: 17.037 MiB)
>>> import pandas as pd
>>> import time
>>> start=time.time()
>>> myData=pd.read_csv("myFile.txt",sep="|",header=None,low_memory=False)
>>> print(time.time()-start)
0.07587623596191406
using CSV
@time df=CSV.read("C:/Users/hafez/personal/r/tutorial for students/Book2.csv")