我在文件data.txt
中有一个浮点数的数据集,每行包含可变数量的列。例如:
3.0 2.5
1.1 30.2 11.5
5.0 6.2
12.2 70.2 14.7 3.2 1.1
为了阅读它,我可以轻松地在Matlab中使用fopen
和fscanf
的组合。最后一个按列顺序读取数据并将其转换为数组,如下所示:
array = [3.0 2.5 1.1 30.2 11.5 5.0 6.2 12.2 70.2 14.7 3.2 1.1]'
我想将我的Matlab代码翻译成Python。但由于没有Python内置函数替换Matlab的fscanf
,我编写了以下Python代码,以与描述相同的方式读取和重塑数据:
from numpy import *
data = []
with open('data.txt') as file:
for line in file:
cline = line.split()
data = data + cline
data = array(data)
这样可行,但我的一些数据集最多可以包含200,000行,而我所显示的Python代码对于大数据集的读取速度非常慢(大约10分钟)。另一方面,Matlab的fscanf
只需几秒钟或更短的时间完成工作。那么,有没有比我的代码更快(优化)的方法在Python中执行此操作?
我真的很感激任何建议。
答案 0 :(得分:2)
在几千行之后,这需要做大量的额外工作:
this.saveAs(fileName);
只需 data = data + cline
。 (或data.extend(cline)
,如果你想知道哪一个数字一起出现在一条线上。)
考虑存储双打而不是文本:
.append()
答案 1 :(得分:2)
numpy.loadtxt
在这里完美无法应用,因为列数会发生变化。
你想要一个平面列表,你可以通过使用列表理解来加快它的速度:
from numpy import *
with open("file.txt") as f:
data = array([float(x) for l in f for x in l.split()])
(现在我很确定考虑到JH在他的回答中指出的错误会更快:data = data + line
每次创建一个新列表:二次复杂性。你可以通过列表补偿来避免这种情况)
答案 2 :(得分:2)
Pandas处理乱七八糟的列比numpy更好/更快,并且应该比带循环的vanilla python实现更快。
使用read_csv
,然后使用stack
,然后访问values
属性以返回numpy
数组。
max_per_row = 10 # set this to the max possible number of elements in a row
vals = pd.read_csv(buf, header=None, names=range(max_per_row),
delim_whitespace=True).stack().values
print(vals)
array([ 3. , 2.5, 1.1, 30.2, 11.5, 5. , 6.2, 12.2, 70.2,
14.7, 3.2, 1.1])