Python缩短了数据导入时间

时间:2019-01-02 12:31:38

标签: python

我有一个包含以下内容的数据文件:

somename = [ [1,2,3,4,5,6],...plus other such elements making a 60 MB file called somefile.py ]

在我的python脚本(与数据位于同一文件夹中)中,我只有(以及与此相应的shebang一起使用):

from somefile import somename

这花了将近20分钟才能完成。如何改善这种导入?

我在Mac osx 10.13上使用python 3.7。

2 个答案:

答案 0 :(得分:3)

将文件加载为“ Python源代码”总是比较慢的,但是加载60MiB文件20分钟似乎太慢了。 Python使用完整的lexer/parser,并执行诸如跟踪源位置以进行准确的错误报告等操作。它的语法是deliberately simple,语法解析相对较快,但仍然比其他文件格式要慢得多。

我会提出其他建议之一,但是认为比较不同文件格式的时间会很有趣

首先,我生成一些数据:

somename = [list(range(6)) for _ in range(100_000)]

这需要152毫秒来完成我的计算机,然后可以使用以下命令将其保存在“ Python源文件”中:

with open('data.py', 'w') as fd:
    fd.write(f'somename = {somename}')

耗时84.1毫秒,使用以下命令重新加载它:

from data import somename

这需要1.40秒的时间-我尝试了其他一些大小,缩放比例似乎在数组长度上呈线性,这给我留下了深刻的印象。然后,我开始使用不同的文件格式JSON:

import json

with open('data.json', 'w') as fd:
    json.dump(somename, fd)

with open('data.json') as fd:
    somename = json.load(fd)

此处保存时间为787毫秒,加载时间为131毫秒。接下来,CSV:

import csv

with open('data.csv', 'w') as fd:
    out = csv.writer(fd)
    out.writerows(somename)

with open('data.csv') as fd:
    inp = csv.reader(fd)
    somename = [[int(v) for v in row] for row in inp]

保存花费了114毫秒,而加载花费了329毫秒(如果未将字符串转换为int,则节省了129毫秒)。接下来,我尝试了musbur对pickle的建议:

import pickle  # no need for `cPickle` in Python 3

with open('data.pck', 'wb') as fd:
    pickle.dump(somename, fd)

with open('data.pck', 'rb') as fd:
    somename = pickle.load(fd)

保存时间为49.1毫秒,加载时间为128毫秒

带回家的消息似乎是,将数据保存到源代码中所需的时间是原来的10倍,但我不确定这将使您的计算机花费20分钟的时间!

答案 1 :(得分:0)

somename.py文件显然是由某些软件创建的。如果定期重新创建(即经常更改),则应以创建更易于在Python中导入的数据(如表格文本数据,JSON,yaml,...)的方式重写其他软件。 )。如果是永远不变的静态数据,请执行以下操作:

set.seed(123)

n <- 10000L
m <- matrix(rnorm(2*n), n, 2)
m2 <- m[, 2]

object_size(m)
## 160 kB
object_size(m2)
## 80 kB
object_size(m, m2) 
## 240 kB  <-- unlike for data.frames this equals sum of above

这会将您的数据序列化为文件“ data.pck”,可以非常快速地从该文件中重新加载数据。