【发布时间】:2011-11-27 11:54:08
【问题描述】:
一个完整的 Python 新手的问题。
我有一个列数组,我需要根据应用于另一个数组的条件语句将某些值强制为零。我找到了两种解决方案,它们都提供了正确的答案。但是对于我通常需要的较大数组(>1E6 个元素)来说,它们都非常耗时——而且我怀疑这是一种糟糕的编程技术。这两个版本是:
from numpy import zeros,abs,multiply,array,reshape
def testA(y, f, FC1, FC2):
c = zeros((len(f),1))
for n in xrange(len(f)):
if abs(f[n,0]) >= FC1 and abs(f[n,0]) <= FC2:
c[n,0] = 1.
w = multiply(c,y)
return w
def testB(y, f, FC1, FC2):
z = [(abs(f[n,0])>=FC1 and abs(f[n,0])<=FC2) for n in xrange(len(f))]
z = multiply(array(z,dtype=float).reshape(len(f),1), y)
return z
输入数组是列数组,因为这与要完成的后期处理相匹配。测试可以这样完成:
>>> from numpy.random import normal as randn
>>> fs, N = 1.E3, 2**22
>>> f = fs/N*arange(N).reshape((N,1))
>>> x = randn(size=(N,1))
>>> w1 = testA(x,f,200.,550.)
>>> z1 = testB(x,f,200.,550.)
在我的笔记本电脑上,testA 需要 18.7 秒,testB 需要 19.3 - N=2**22。在 testB 中,我还尝试包含 "z = [None]*len(f)" 以按照另一个线程中的建议进行预分配,但这并没有什么区别。
我有两个问题,希望得到相同的答案:
- 什么是“正确”的 Python 解决方案?
- 我可以做些什么来更快地得到答案?
例如,我故意不使用任何时间使用已编译的 Python - 我想先有一些工作代码。希望还有一些东西,这是很好的 Python 风格。我希望能够得到 N=2**22 的执行时间低于两秒左右。此特定操作将被多次使用,因此执行时间很重要。
如果问题很愚蠢,我提前道歉 - 我无法在大量并不总是易于访问的 Python 文档或其他线程中找到答案。
【问题讨论】:
-
y、f和返回值是否需要使用数组?为什么不使用列表呢?
-
在接下来的处理中,我需要做一堆矩阵运算,我希望它是最简单的(以及代码用户所期望的)留在数组中。但如果列表更好,我也许可以稍后转移到数组。
-
HYRY 的提案效果很好。它在我的笔记本电脑上将时间缩短到 0.4 秒以下。我对此非常满意。非常感谢您的帮助!非常感谢。
标签: python arrays conditional