Если ваши сигмы все одинаковые, вы можете достичь этого без любого l oop, используя scipy.signal.convolve2d
.
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import convolve2d
from scipy.stats import multivariate_normal
sigma = 3
width = 200 # smaller than yours so you can see the single pixels
n_stars = 50
# draw some random stars
star_row = np.random.randint(0, width, n_stars)
star_col = np.random.randint(0, width, n_stars)
star_amplitude = np.random.normal(50, 10, n_stars)
# assign amplitudes to center pixel of stars
amplitudes = np.zeros((width, width))
amplitudes[star_row, star_col] = star_amplitude
# create 2d gaussian kernel
row = col = np.arange(-4 * sigma, 4 * sigma + 1)
grid = np.stack(np.meshgrid(row, col)).T
kernel = multivariate_normal(
[0, 0],
[[sigma**2, 0], [0, sigma**2]]
).pdf(grid)
kernel /= kernel.sum()
# convolve with 2d gaussian
final = convolve2d(amplitudes, kernel, mode='same')
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(9, 3))
img = ax1.imshow(amplitudes)
fig.colorbar(img, ax=ax1)
ax1.set_label('Before Convolution')
img = ax2.imshow(kernel)
fig.colorbar(img, ax=ax2)
ax2.set_label('Convolution Kernel')
img = ax3.imshow(final)
fig.colorbar(img, ax=ax3)
ax3.set_label('After Convolution')
fig.tight_layout()
fig.savefig('conv2d.png', dpi=300)
Результат:
Если сигмы различаются, вы получаете способ с одним l oop над возможными сигмами.