【问题标题】:How to receive tuple as an argument to a function in python 3?如何在 python 3 中接收元组作为函数的参数?
【发布时间】:2020-03-08 13:56:14
【问题描述】:

我有一些在 python2 中运行良好的代码。我需要把它翻译成python3。 有一点我不明白如何适应。

这是一些代码。

有错误的函数

def gauss((x, y), x0, y0, intens, sigma):
    return intens*numpy.exp(-(numpy.power(x-x0, 2)+numpy.power(y-y0, 2))/(2.*sigma**2)).ravel()

调用函数

def dofwhm(psfdata):
    x = numpy.arange(psfdata.shape[1])
    y = numpy.arange(psfdata.shape[0])
    x, y = numpy.meshgrid(x, y)
    popt, pcov = opt.curve_fit(gauss, (x, y), psfdata.ravel(), p0=[psfdata.shape[1]/2, psfdata.shape[0]/2, psfdata[psfdata.shape[1]/2, psfdata.shape[0]/2], 5.0])

    return 2.355*abs(popt[3])

我得到的错误是

Traceback (most recent call last):
  File "catalog.py", line 8, in <module>
    import cutPsf
  File "/Users/igor/GALPHAT/pypygalphat/preprocessingNew/cutPsf.py", line 9
    def gauss((x, y), x0, y0, intens, sigma):
              ^
SyntaxError: invalid syntax

有人可以帮我如何适应 python3 吗?

更新: 好吧,@hpaulj 的答案似乎是正确的。我发现有例程可以将 Python2 代码转换为 Python3 代码。结果在目标文件 2to3 -w cutPsf.py 上运行后,我从 hpaulj 获得了建议的解决方案。不幸的是,它导致了休闲错误:

Traceback (most recent call last):
  File "catalog.py", line 323, in <module>
    cutPsf.run(tempDir+galaxy.psffile, outDirFits+galaxy.psffile)
  File "/Users/igor/GALPHAT/pypygalphat_p3/preprocessingNew/cutPsf.py", line 63, in run
    coeffwhm = dofwhm(newPsf)
  File "/Users/igor/GALPHAT/pypygalphat_p3/preprocessingNew/cutPsf.py", line 20, in dofwhm
    psfdata.shape[1]/2, psfdata.shape[0]/2, psfdata[psfdata.shape[1]/2, psfdata.shape[0]/2], 5.0])
IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices

如前所述,一切都可以在 Python2 中完美运行...

【问题讨论】:

  • def gauss((x, y), x0,... 是您的代码,还是来自导入的库?
  • @hpaulj 不能肯定,我不是作者...
  • 在py2中,/是整数除;在 py3 中,结果可能是浮动的。 // 进行整数除法。 psfdata[psfdata.shape[1]/2, psfdata.shape[0]/2] 中的 /2 可能是导致问题的原因。同样较新的numpy 对浮点索引更挑剔;旧版本往往会让这种情况发生。
  • 是的,// 代替 / 仅适用。也许将它添加到答案中会很好。

标签: python-3.x python-2.7 numpy scipy gauss


【解决方案1】:

您需要使用 * 运算符进行一些修改。

def gauss(x, y, x0, y0, intens, sigma):
    return intens*numpy.exp(-(numpy.power(x-x0, 2)+numpy.power(y-y0, 2))/(2.*sigma**2)).ravel()

def dofwhm(psfdata):
    x = numpy.arange(psfdata.shape[1])
    y = numpy.arange(psfdata.shape[0])
    x, y = numpy.meshgrid(x, y)
    popt, pcov = opt.curve_fit(gauss, *(x, y), psfdata.ravel(), p0=[psfdata.shape[1]/2, psfdata.shape[0]/2, psfdata[psfdata.shape[1]/2, psfdata.shape[0]/2], 5.0])

    return 2.355*abs(popt[3])

【讨论】:

  • 在你成功之后:我得到了 popt,pcov = opt.curve_fit(gauss, *(x, y), psfdata.ravel(), p0=[psfdata.shape[1]/2, psfdata .shape[0]/2, psfdata[psfdata.shape[1]/2, psfdata.shape[0]/2], 5.0]) IndexError: only integers, slices (:), ellipsis (...) , numpy.newaxis (None) 和整数或布尔数组是有效的索引
  • popt, pcov = opt.curve_fit(gauss, x, y, psfdata.ravel(), p0=[psfdata.shape[1]/2, psfdata.shape[0]/2, psfdata [psfdata.shape[1]/2, psfdata.shape[0]/2], 5.0]) 可以在opt.curve_fit函数中直接将(x, y)展开为x, y吗?
【解决方案2】:

稍后再拆包

def gauss(xy, x0, y0, intens, sigma):
    x, y = xy
    return intens*numpy.exp(-(numpy.power(x-x0, 2)+numpy.power(y-y0, 2))/(2.*sigma**2)).ravel()

我根据典型的scipy 优化要求提出了这个建议,其中使用f(x, *args) 调用用户定义的函数,其中x 是优化的变量(可能是数组)。但curve_fit 不同。

scipy.optimize.curve_fit(f, xdata, ydata, p0=None,...)

f(你的gauss?)满足的地方:

ydata = f(xdata, *params) + eps 

https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html

如果xdata(x,y) 元组或由它组成的数组,我想我的建议仍然有效。而ydata 就是psfdata.ravel()

【讨论】:

  • 我已根据您的建议更新了操作。
猜你喜欢
  • 1970-01-01
  • 2017-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-23
  • 2014-06-27
  • 1970-01-01
相关资源
最近更新 更多