在物理学的某些领域中,相位因子,如(-1)^n,其中n是通过求和或减去其他整数而形成的整数,经常出现。总体而言,是否有以下方面的绩效改进:

sgn = lambda k: -1 if k % 2 else 1

太简单了
sgn = (-1)**k

如果是这样的话,那么将前者矢量化的最佳方法是什么?
编辑:E先生提供了一个在整数范围内有界的k的快速解决方案,但我有点担心我的k可能会超出这个范围。最初我想:
In [1]: sg = np.array([1,-1])
In [2]: k = np.array([201, 0, 2, -37])
In [3]: sg[k % 2]
Out[4]: array([-1,  1,  1, -1])

但是,与功率法相比,模数运算似乎减慢了速度:
ph1 = lambda k: (-1)**k
sgn = np.array([1,-1])
ph2 = lambda k: sgn[k % 2]

x = np.random.randint(-200, 200, 100)
%timeit ph1(x)
1000000 loops, best of 3: 264 ns per loop

%timeit ph2(x)
1000000 loops, best of 3: 284 ns per loop

最佳答案

Mr E has answered how to vectorise it with numpy,但对于哪个时间段更有效,下面的代码对timeit的各种值使用k,并使用matplotlib绘制结果。
结果表明,使用-1 if k % 2 else 1始终比使用(-1)**k快。

import matplotlib.pyplot as plt

from timeit import Timer

def f1(k): return -1 if k % 2 else 1
def f2(k): return (-1)**k

result1 = []
result2 = []

x = range(0,1000, 100)
for n in x:
    print(n)

    timer1 = Timer('f1({})'.format(n), setup='from __main__ import f1')
    timer2 = Timer('f2({})'.format(n), setup='from __main__ import f2')

    result1.append(timer1.timeit(100000))
    result2.append(timer2.timeit(100000))

plt.plot(x, result1, label='-1 if k % 2 else 1')
plt.plot(x, result2, label='(-1)**k')

plt.xlabel('k')
plt.ylabel('Time')

plt.legend(loc='best')

plt.show()

10-08 13:38