我有一个函数
gen()
,它返回一个由 nElements
个浮点数组成的 numpy 数组。我正在寻找一种更Pythonic(单行?)的方法来执行以下操作:
a = zeros((nSamples, nElements))
for i in xrange(nSamples):
a[i,:] = gen()
这是一种方法:
a = array([gen() for i in xrange(nSamples)]).reshape((nSamples, nElements))
但是由于没有预先分配 numpy 数组,所以速度会慢一些,这是可以理解的:
import time
from numpy import *
nSamples = 100000
nElements = 100
start = time.time()
a = array([gen() for i in xrange(nSamples)]).reshape((nSamples, nElements))
print (time.time() - start)
start = time.time()
a = zeros((numSamples, nElements))
for i in xrange(numSamples):
a[i,:] = gen()
print (time.time() - start)
输出:
1.82166719437
0.502261161804
有没有一种方法可以实现相同的单行,同时保持预先分配的数组以提高速度?
这可能无法直接回答您的问题,但是既然您在标题中提到了Pythonic...请理解Pythonic不一定是“单行”或最聪明和最短(按击键方式)的方式做某事。恰恰相反——Pythonic 代码力求清晰。
就您的代码而言,我发现:
a = zeros((nSamples, nElements))
for i in xrange(nSamples):
a[i,:] = gen()
比以下更清楚:
a = array([gen() for i in xrange(nSamples)]).reshape((nSamples, nElements))
因此我不会说第二个更Pythonic。可能不太如此。
我相信这会做你想要的:
a = vstack([ gen() for _ in xrange(nSamples) ])
由于我无法访问您的
gen
功能,因此我无法进行计时测试。另外,这(以及你的单行)不像你的 for 循环版本那么内存友好。单行存储所有 gen()
输出,然后构造数组,而 for 循环一次只需要在内存中保存一个 gen()
(以及 numpy 数组)。