【问题标题】:Python - lambda in list comprehension gives wrong resultPython - 列表理解中的 lambda 给出错误的结果
【发布时间】:2016-05-08 20:18:38
【问题描述】:

我得到了一个 numpy.ndarray 电磁样本作为复数,格式如下:

ex1:
[[  8.23133235e-15,  -1.59200901e-15,  -4.39818917e-13,   7.68089585e-13]
 [  6.98151957e-15,  -1.20306059e-15,   9.83923013e-13,   1.64838108e-11]
 [  8.41053742e-15,  -1.77702007e-15,  -5.98961364e-13,   8.97436205e-13]
 [  7.08443026e-15,  -1.25262430e-15,   1.11415868e-12,   1.69346186e-11]]

其中行交替组成实部和虚部:

[[z1Ex.real, z1Ey.real, z1Hx.real, z1Hy.real],
 [z1Ex.imag, z1Ey.imag, z1Hx.imag, z1Hy.imag],
 [z2Ex.real, z2Ey.real, z2Hx.real, z2Hy.real],
 [z2Ex.imag, z2Ey.imag, z2Hx.imag, z2Hy.imag],
        ...etc.]

我想要创建一个以幅度和相位表示数据的新数组,但保持相同的格式(即用幅度行替换实数行,用相位行替换虚数行)。

我设法为这两种计算提供了列表推导(我很自豪,作为一个 2 周的业余爱好者,所以请保持温和;))。幅度的结果是我所期望的,但是相位非常偏离,我不知道为什么......

我的做法:

  1. 将原始数组分割成 real 和 imag 子数组:

    import numpy, cmath
    
    real = ex1[::2] #numpy.ndarray
    imag = ex1[1::2] #numpy.ndarray
    
  2. 在列表理解之外定义 lambda:

    magcalc = lambda z, y: abs(complex(z, y))
    phasecalc = lambda z,y: cmath.phase(complex(z, y))
    
  3. 定义列表推导以对子数组进行数学运算:

    real[:] = np.array([[magcalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(real))])
    
    imag[:] = np.array([[phasecalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(imag))])
    
  4. 检查原始数组中的结果:

    print ex1[:4]
    

如果我这样做,第一个 Ex 样本的相位结果是 0.574 rad。如果我手动检查相位(即cmath.phase(complex(z1Ex.real,z1Ex.imag))),那么我会得到0.703 rad。如果我的列表理解中有错误,我会接受,但幅度结果是完全正确的,所以我怀疑就是这样。

我哪里做错了?我真的试图找出连续两天,没有运气......另外,我想不出另一种方法来实现我想要的。

请帮助...(使用 Python 2.7)

谢谢 尼尔斯

【问题讨论】:

  • 感谢您编写了一个非常清晰的逐步复制问题。但是,在我执行[[phasecalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(imag))] 的最后一步时,我确实得到0.70342 作为第一个结果。所以我想这与你如何将此结果分配给其他数组有关,但你没有准确地向我们展示phaserow 是什么所以我无法分辨。
  • 感谢您的尝试,约翰,非常感谢。抱歉,我将原始代码中的数组重命名为更清晰,但我忘了重命名最后两个。我刚刚更正了那部分。好奇,如果你真的用同样的方法得到正确的结果......

标签: python-2.7 lambda list-comprehension


【解决方案1】:

哦,天哪.. 现在我看到了问题,不敢相信我的密度有多大...感谢 John,让我重新思考变量分配。

imag[:] = np.array([[phasecalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(imag))]) 中,我指的是real[],好像它仍然填充了实际值。但是我更改了real[] 之前的行以包含幅度...因此,只需更改列表推导的变量名称即可:

  1. 定义列表推导以对子数组进行数学运算:

    realcopy[:] = np.array([[magcalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(real))])
    
    imagcopy[:] = np.array([[phasecalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(imag))])
    

然后重新分配给原始磁力、相位阵列:

  1. 检查原始结果

    real[:] = realcopy
    imag[:] = imagcopy
    
    print ex1[:4]
    

抱歉浪费了时间和字节...

干杯 尼尔斯

【讨论】:

  • 很高兴你把它整理好了。您可以“接受”您自己的答案(我知道您必须先等待一个计时器),或者删除该问题,因为它可能对其他人没有用。 :)
猜你喜欢
  • 1970-01-01
  • 2015-03-10
  • 2018-02-09
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
  • 2014-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多