2012-07-17 122 views
4

我有一个3000x300矩阵文件(float)。当我读取并转换为浮点数时,我得到了float64,这是python中的默认值。我尝试了numpy和map()将它转换为float32(),但它们看起来效率很低。将字符串列表有效地转换为float32

我的代码:采取

x = open(readFrom, 'r').readlines() 
y = [[float(i) for i in s.split()] for s in x] 

时间:0:00:00.996000

numpy的实现:采取

x = open(readFrom, 'r').readlines() 
y = [[np.float32(i) for i in s.split()] for s in x] 

时间:0:00:06.093000

地图()

采取
x = open(readFrom, 'r').readlines() 
y = [map(np.float32, s.split()) for s in x] 

时间:0:00:05.474000

我怎么能转换为非常有效地FLOAT32?

谢谢。

Update:

numpy.loadtxt()numpy.genfromtxt()不适合大文件的工作(给内存错误)。我发布了一个与此相关的问题,我在这里介绍的方法适用于巨大的矩阵文件(50,000x5000)。 here is the question

回答

2

如果内存问题,并且如果您事先知道该字段的大小,则可能不希望首先读取整个文件。像这样的东西可能更合适:

#allocate memory (np.empty would work too and be marginally faster, 
#     but probably not worth mentioning). 
a=np.zeros((3000,300),dtype=np.float32) 
with open(filename) as f: 
    for i,line in enumerate(f): 
     a[i,:]=map(np.float32,line.split()) 

从我的机器上一对夫妇快速(和令人惊讶的)测试,看来map甚至可能不是必要的:

a=np.zeros((3000,300),dtype=np.float32) 
with open(filename) as f: 
    for i,line in enumerate(f): 
     a[i,:]=line.split() 

这可能不是速度最快,但它当然是最有效的内存管理方式。

一些测试:

import numpy as np 

def func1(): #No map -- And pretty speedy :-). 
    a=np.zeros((3000,300),dtype=np.float32) 
    with open('junk.txt') as f: 
     for i,line in enumerate(f): 
      a[i,:]=line.split() 

def func2(): 
    a=np.zeros((3000,300),dtype=np.float32) 
    with open('junk.txt') as f: 
     for i,line in enumerate(f): 
      a[i,:]=map(np.float32,line.split()) 

def func3(): 
    a=np.zeros((3000,300),dtype=np.float32) 
    with open('junk.txt') as f: 
     for i,line in enumerate(f): 
      a[i,:]=map(float,line.split()) 

import timeit 

print timeit.timeit('func1()',setup='from __main__ import func1',number=3) #1.36s 
print timeit.timeit('func2()',setup='from __main__ import func2',number=3) #11.53s 
print timeit.timeit('func3()',setup='from __main__ import func3',number=3) #1.72s 
+0

感谢@mgilson,如果我没有发现任何其他有效的方法。我需要解决这个问题。 – Maggie 2012-07-17 18:11:08

+0

3000×300矩阵文件需要的时间是'0:00:05.885000' – Maggie 2012-07-17 18:16:47

+1

@Mahin - 如果使用map(float,line.split())而不是map(np.float32,line.split ))'?你实际上可能会看到性能提升(从“向量化”演员阵容从“double”到“float”)... – mgilson 2012-07-17 18:59:49