移调时的numpy和octave不同

Xtr*_*oce 3 numpy fft octave

首先我知道在这里有一个相同的问题答案:Matlab中的FFT和numpy/scipy给出不同的结果, 但那里给出的答案对我做的测试不起作用:

当我从numpy.fft做一个fft我得到以下结果:

In [30]: numpy.fft.fft(numpy.array([1+0.5j, 3+0j, 2+0j, 8+3j]))
Out[30]: array([ 14.+3.5j,  -4.+5.5j,  -8.-2.5j,   2.-4.5j])
Run Code Online (Sandbox Code Playgroud)

这与我的八度音程的输出完全相同)

octave:39> fft([1+0.5j,3+0j,2+0j,8+3j])
ans =
Columns 1 through 3:
14.0000 +  3.5000i   -4.0000 +  5.5000i   -8.0000 -  2.5000i
Column 4:
2.0000 -  4.5000i
Run Code Online (Sandbox Code Playgroud)

但如果我将列表转换为octave和python我得到:

In [9]: numpy.fft.fft(numpy.array([1+0.5j, 3+0j, 2+0j, 8+3j]).transpose())
Out[9]: array([ 14.+3.5j,  -4.+5.5j,  -8.-2.5j,   2.-4.5j])
Run Code Online (Sandbox Code Playgroud)

和八度:

octave:40> fft([1+0.5j,3+0j,2+0j,8+3j]')
ans =

14.0000 -  3.5000i
2.0000 +  4.5000i
-8.0000 +  2.5000i
-4.0000 -  5.5000i
Run Code Online (Sandbox Code Playgroud)

我也尝试在python中重塑,但这会导致:

In [33]: numpy.fft.fft(numpy.reshape(numpy.array([1+0.5j,3+0j,2+0j,8+3j]), (4,1)))
Out[33]: 
array([[ 1.+0.5j],
   [ 3.+0.j ],
   [ 2.+0.j ],
   [ 8.+3.j ]])
Run Code Online (Sandbox Code Playgroud)

如何在python中获得与八度音阶相同的结果?+我没有matlab来测试,否则我会检查它是否返回与octave相同只是为了确定.

unu*_*tbu 5

为什么NumPy和octave给出了不同的结果:

输入是不同的.将'在八度返回共轭复数,而不是转置,.':

octave:6> [1+0.5j,3+0j,2+0j,8+3j]'
ans =

   1.0000 - 0.5000i
   3.0000 - 0.0000i
   2.0000 - 0.0000i
   8.0000 - 3.0000i
Run Code Online (Sandbox Code Playgroud)

所以要使NumPy的结果匹配八度:

In [115]: np.fft.fft(np.array([1+0.5j, 3+0j, 2+0j, 8+3j]).conj()).reshape(-1, 1)
Out[115]: 
array([[ 14.-3.5j],
       [  2.+4.5j],
       [ -8.+2.5j],
       [ -4.-5.5j]])

octave:7> fft([1+0.5j,3+0j,2+0j,8+3j]')
ans =

   14.0000 -  3.5000i
    2.0000 +  4.5000i
   -8.0000 +  2.5000i
   -4.0000 -  5.5000i
Run Code Online (Sandbox Code Playgroud)

在NumPy中,1D阵列的转置是相同的1D阵列.这就是fft(np.array([1+0.5j, 3+0j, 2+0j, 8+3j]).transpose())返回一维数组的原因.

在采用1D阵列的FFT后重新整形:

您可以先进行FFT,然后重新整形.要制作二维一维数组,您可以使用reshape获得一个类似于列的数组(4,1),或者使用np.atleast_2d后跟transpose:

In [115]: np.fft.fft(np.array([1+0.5j, 3+0j, 2+0j, 8+3j]).conj()).reshape(-1, 1)
Out[115]: 
array([[ 14.-3.5j],
       [  2.+4.5j],
       [ -8.+2.5j],
       [ -4.-5.5j]])
Run Code Online (Sandbox Code Playgroud)

要么

In [116]: np.atleast_2d(np.fft.fft(np.array([1+0.5j, 3+0j, 2+0j, 8+3j]).conj())).T
Out[116]: 
array([[ 14.-3.5j],
       [  2.+4.5j],
       [ -8.+2.5j],
       [ -4.-5.5j]])
Run Code Online (Sandbox Code Playgroud)

采用2D阵列的FFT:

np.fft.fft默认情况下,FFT会在最后一个轴上进行.这就是为什么重塑形状(4,1)不起作用的原因.相反,将数组重塑为(1,4):

In [117]: np.fft.fft(np.reshape(np.array([1+0.5j,3+0j,2+0j,8+3j]), (1,4)).conj()).T
Out[117]: 
array([[ 14.-3.5j],
       [  2.+4.5j],
       [ -8.+2.5j],
       [ -4.-5.5j]])
Run Code Online (Sandbox Code Playgroud)

或者你可以np.matrix用来制作形状的二维矩阵(1,4).同样,FFT在最后一个轴上进行,返回一个形状(1,4)的数组,然后您可以转置它以获得所需的结果:

In [121]: np.fft.fft(np.matrix([1+0.5j, 3+0j, 2+0j, 8+3j]).conj()).T
Out[121]: 
array([[ 14.-3.5j],
       [  2.+4.5j],
       [ -8.+2.5j],
       [ -4.-5.5j]])
Run Code Online (Sandbox Code Playgroud)

这或许可以为您提供最新的语法.但要注意,这会传递一个np.matrix输入但返回一个np.ndarray输出.


正如Warren Weckesser指出的那样,如果你已经拥有了一个2D NumPy数组,并希望对其列进行FFT,那么你可以将axis=0调用传递给np.fft.fft.此外,matrix该类(与ndarray类不同)具有H返回复共轭转置的属性.从而

In [114]: np.fft.fft(np.matrix([1+0.5j, 3+0j, 2+0j, 8+3j]).H, axis=0)
Out[114]: 
array([[ 14.-3.5j],
       [  2.+4.5j],
       [ -8.+2.5j],
       [ -4.-5.5j]])
Run Code Online (Sandbox Code Playgroud)