numpy 如何在阵列中生成多个2D高斯源?

b91juud3  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(100)

我想在fits数组中生成一些高斯源。代码在下面。

from astropy.io import fits
from numpy import *
xx=yy=1024
xc=xx/2.;yc=yy/2.
A=10.0
gau=zeros([xx,yy])
for i in range(xx):
  for j in range(yy):
      gau[i,j]=  A*exp(-((i-xc)/50.)**2 - ((j-yc)/50.)**2)
fits.writeto('gaussian_model.fits',gau,overwrite=True)

我对n数字进行了迭代,并在fits文件中添加了所有高斯型。这是非常缓慢的(xx,yy)n号码。有没有其他有效的方法可以加快n源代码在(xx,yy)上的迭代速度?

kuuvgm7e

kuuvgm7e1#

为了在numpy中有效地实现2d高斯,你应该注意到2d高斯是可分离的,可以通过将两个1d高斯相乘来实现,将传递给np.exp的参数的大小(这是昂贵的)从M * N减少到M + N

xx = 1024
yy = 1024

xc = xx / 2.
yc = yy / 2.
A = 10.0
x = np.arange(xx, dtype=np.float64)[:, None]
y = np.arange(yy, dtype=np.float64)[None, :]

x -= xc
y -= yc
x /= 50.
y /= 50.
x **= 2
y **= 2
x *= -1.
y *= -1.
x_exp = np.exp(x, out=x)
y_exp = np.exp(y, out=y)
A * x_exp * y_exp

时间:

def op(xx=1024, yy=1024):
    xc=xx/2.;yc=yy/2.
    A=10.0
    gau=np.zeros([xx,yy])
    for i in range(xx):
        for j in range(yy):
            gau[i,j]=  A*np.exp(-((i-xc)/50.)**2 - ((j-yc)/50.)**2)
    return gau

def jared(xx=1024, yy=1024):

    xc = xx/2.
    yc = yy/2.

    A = 10.0

    XX, YY = np.meshgrid(np.arange(xx), np.arange(yy))
    return A*np.exp(-((XX-xc)/50.)**2 - ((YY-yc)/50.)**2)

def nin17(xx=1024, yy=1024):
    # Code from above

assert np.allclose(op(), jared())
assert np.allclose(op(), nin17())

%timeit op()
%timeit jared()
%timeit nin17()

结果如下:

608 ms ± 5.71 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
8.64 ms ± 518 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
905 µs ± 10.1 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
chy5wohz

chy5wohz2#

你可以使用向量化(vectorization)来加速你的代码。对整个数组使用numpy而不是循环,本质上是将循环推到编译的C代码中,这更快)。这可以使用np.meshgrid来制作xxyy的组合数组(本质上是创建xxyy组合的数组),或者通过添加新轴来使用broadcasting。对于这两种方法,您都必须创建xxyy值的向量,我使用np.arange(numpy用于创建具有给定间距的列表的方法,默认值为1)。

import numpy as np

xx = 1024
yy = 1024

xc = xx/2.
yc = yy/2.

A = 10.0

YY, XX = np.meshgrid(np.arange(yy), np.arange(xx))
# or
# XX = np.arange(xx)[:, None]
# YY = np.arange(yy)[None, :]
gau = A*np.exp(-((XX-xc)/50.)**2 - ((YY-yc)/50.)**2)

你应该读一下numpy basics here。如果你用numpy数组写循环,那么你可能做错了什么。
此外,使用*导入也是不好的做法。

相关问题