复数numpy数组的实部缩放

4

我有一个复数向量(FFT的结果),我想仅按另一个向量中的因子缩放复数的实部。

示例

cplxarr= np.array([1+2j, 3+1j, 7-2j])
factarr= np.array([.5, .6, .2])
# desired result of cplxarr * factarr :
# np.array([.5+2j 1.8+1j 1.4-2j])

这篇文章主要涉及人类听觉频率响应的一个非常具体的设置。
显然,如上所述,向量的乘法也会缩放虚部。

我应该如何设置factarr以及需要执行什么操作才能达到所需的结果?如果可能的话,不分离实部和虚部、缩放实部并重新组合为新的复向量。

1个回答

8
这样做就可以了:
>>> factarr*cplxarr.real + (1j)*cplxarr.imag
array([ 0.5+2.j,  1.8+1.j,  1.4-2.j])

我不确定这是否是最好的方法。


事实证明,对于我来说至少(OS-X 10.5.8,python 2.7.3,numpy 1.6.2),这个版本比使用np.vectorize的另一个版本快大约两倍:

>>> from timeit import timeit
>>> timeit('factarr*cplxarr.real+(1j)*cplxarr.imag',setup='from __main__ import factarr,cplxarr')
21.008132934570312
>>> timeit('f(cplxarr.real * factarr, cplxarr.imag)',setup='from __main__ import factarr,cplxarr; import numpy as np; f=np.vectorize(np.complex)')
46.52931499481201

使用python提供的np.complexcomplex似乎没有太大区别:

>>> timeit('f(cplxarr.real * factarr, cplxarr.imag)',setup='from __main__ import  factarr,cplxarr; import numpy as np; f=np.vectorize(complex)')
44.87726283073425

目前排名第一的计时器(由下面评论中的eryksun提出)

>>> timeit.timeit('a = cplxarr.copy(); a.real *= factarr ',setup='from __main__ import factarr,cplxarr')
8.336654901504517

并且证明它是有效的:

>>> a = cplxarr.copy()
>>> a.real *= factarr 
>>> a
array([ 0.5+2.j,  1.8+1.j,  1.4-2.j])

如果您想要在原地执行操作(并因此可以省略复制过程),那么这显然会更快。


我更喜欢你的版本而不是我的。 - NPE
2
@tzot:你想要原地完成吗?那只需要 cplxarr.real *= factarr。否则,你可以尝试使用 [:] 复制,然后对 real 分量进行原地缩放。 - Eryk Sun
1
@eryksun -- 我认为ndarray.copy在复制时可能更好。当处理np.ndarrays时,[:]应该返回一个视图而不是副本。但是直接在原地更新实际组件是个好主意。 - mgilson
是的,eryksun的建议正是我想要的;如果eryksun将其添加为他们的答案,我会选择那个而不是这个,但我相信这个答案将成为本地最受欢迎的答案 :) - tzot
谢谢,大家。我明白eryksun的答案是唯一真正就地操作的,而mgilson的初始建议包含了许多临时数组;这解释了速度上的差异。 - tzot
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接