2015-05-26 89 views
4

增量构建numpy数组的最有效方法是什么?一次一行,不提前知道最终尺寸?增量构建numpy数组的最佳方式是什么?

我的用例如下。我需要加载一个大文件(10-100M行),每行需要字符串处理,并且应该形成一个numpy数组的行。

将数据加载到临时Python列表并将其转换为数组还是更好?numpy中的某些现有机制会提高效率吗?

+0

将行添加到现有ndarray与实现'numpy.concatenate'或'numpy.vstack'。单排会是什么样子? – ballsatballsdotballs

+2

'loadtxt'和'genfromtxt'都收集列表(逐行),并将其转换为数组。他们的代码是Python,所以你可以浏览它。 – hpaulj

+1

如果数据格式准确无误且每行都是数据,则可以计算行数并预先分配阵列。这可能不会更快,但是您可以避免创建两个保存相同大量数据的对象。请参阅http://stackoverflow.com/questions/845058/how-to-get-line-count-cheaply-in-python – Alan

回答

4

将每行添加到列表中,然后转换为ndarray后,您应该获得更好的性能。

这是一个测试,我追加ndarrays到列表10000次,然后产生时,我做了一个新的ndarray:

row = np.random.randint(0,100, size=(1,100)) 

,我和IPython的笔记本电脑计时:

%%timeit 
l = [row] 

for i in range(10000): 
    l.append(row) 

n = np.array(l) 

- > 10个循环,最好是3:每个循环132毫秒

这里是我连接每一行的测试:

%%timeit 
l = row 

for i in range(10000): 
    l = np.concatenate((l, row),axis=0) 

- > 1个循环,最好3个:每个循环23.1秒

方式变慢。

第一种方法唯一的问题是您将同时在列表中和列表中都存储,因此您可能会遇到RAM问题。你可以通过分块来避免这种情况。

+0

事实上,它确实有很大的不同,即使我们在追加到列表时创建每一行的副本。 –

1

在我的笔记本电脑1个核英特尔酷睿i5 1.7 GHz的:

%%timeit 
l = [row] 

for i in range(10000): 
    l.append(row) 

n = np.array(l) 
100 loops, best of 3: 5.54 ms per loop 

纯numpy的我最好的尝试(也许某人知道一个更好的解决方案)

%%timeit 
l = np.empty((1e5,row.shape[1])) 
for i in range(10000): 
    l[i] = row 
l = l[np.all(l > 1e-100, axis=1)] 

10 loops, best of 3: 18.5 ms per loop 
+0

有趣的是,使用np.empty预分配仍然不会比列表更快。 – ballsatballsdotballs

+0

好吧,如果我预先分配了适当的大小,速度是相似的。但由于OP预先不知道大小,我不得不使用更大的数组。 – Moritz

相关问题