与Matlab相比,Numpy加载csv太慢

2024-04-26 03:15:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我发布这个问题是因为我想知道我是否做了一些非常错误的事情来得到这个结果。

我有一个中等大小的csv文件,我试图使用numpy来加载它。为了演示,我使用python制作了文件:

import timeit
import numpy as np

my_data = np.random.rand(1500000, 3)*10
np.savetxt('./test.csv', my_data, delimiter=',', fmt='%.2f')

然后,我尝试了两种方法:numpy.genfromtxt,numpy.loadtxt

setup_stmt = 'import numpy as np'
stmt1 = """\
my_data = np.genfromtxt('./test.csv', delimiter=',')
"""
stmt2 = """\
my_data = np.loadtxt('./test.csv', delimiter=',')
"""

t1 = timeit.timeit(stmt=stmt1, setup=setup_stmt, number=3)
t2 = timeit.timeit(stmt=stmt2, setup=setup_stmt, number=3)

结果表明:t1=32.159652940464184,t2=52.00093725634724
但是,当我尝试使用matlab时:

tic
for i = 1:3
    my_data = dlmread('./test.csv');
end
toc

结果表明:经过时间3.196465秒。

我知道装载速度可能有一些差异,但是:

  1. 这比我预料的要多得多
  2. 是不是np.loadtxt应该比np.genfromtxt快?
  3. 我还没有尝试过python csv模块,因为加载csv文件是我经常做的事情,而且对于csv模块,编码有点冗长。。。但如果这是唯一的办法,我很乐意尝试。现在我更关心的是我是否做错了什么。

如有任何意见,将不胜感激。提前多谢!


Tags: 文件csvtestimportnumpydatamynp
3条回答

或许,最好装配一个简单的c代码,将数据转换成二进制文件,并让“numpy”读取二进制文件。我有一个20gbcsv文件要读取,CSV数据是int,double,str的混合体。Numpy读取到结构数组需要一个多小时,而转储到binary需要大约2分钟,加载到Numpy需要不到2秒!

例如,我的特定代码是可用的here

如果您只想保存并读取numpy数组,那么最好根据大小将其保存为二进制或压缩二进制:

my_data = np.random.rand(1500000, 3)*10
np.savetxt('./test.csv', my_data, delimiter=',', fmt='%.2f')
np.save('./testy', my_data)
np.savez('./testz', my_data)
del my_data

setup_stmt = 'import numpy as np'
stmt1 = """\
my_data = np.genfromtxt('./test.csv', delimiter=',')
"""
stmt2 = """\
my_data = np.load('./testy.npy')
"""
stmt3 = """\
my_data = np.load('./testz.npz')['arr_0']
"""

t1 = timeit.timeit(stmt=stmt1, setup=setup_stmt, number=3)
t2 = timeit.timeit(stmt=stmt2, setup=setup_stmt, number=3)
t3 = timeit.timeit(stmt=stmt3, setup=setup_stmt, number=3)

genfromtxt 39.717250824
save 0.0667860507965
savez 0.268463134766

是的,将csv文件读入numpy非常慢。在代码路径上有很多纯Python。现在,即使我使用纯的numpy,我仍然使用pandas作为IO:

>>> import numpy as np, pandas as pd
>>> %time d = np.genfromtxt("./test.csv", delimiter=",")
CPU times: user 14.5 s, sys: 396 ms, total: 14.9 s
Wall time: 14.9 s
>>> %time d = np.loadtxt("./test.csv", delimiter=",")
CPU times: user 25.7 s, sys: 28 ms, total: 25.8 s
Wall time: 25.8 s
>>> %time d = pd.read_csv("./test.csv", delimiter=",").values
CPU times: user 740 ms, sys: 36 ms, total: 776 ms
Wall time: 780 ms

或者,在这个简单的例子中,您可以使用Joe Kington写的here

>>> %time data = iter_loadtxt("test.csv")
CPU times: user 2.84 s, sys: 24 ms, total: 2.86 s
Wall time: 2.86 s

还有Warren Weckesser的textreader库,以防pandas过于依赖:

>>> import textreader
>>> %time d = textreader.readrows("test.csv", float, ",")
readrows: numrows = 1500000
CPU times: user 1.3 s, sys: 40 ms, total: 1.34 s
Wall time: 1.34 s

相关问题 更多 >