Numpy:生成二维高斯和的pdf数组

时间:2018-07-26 18:52:49

标签: python arrays numpy vectorization gaussian

我正在尝试生成一个[600 x 600] numpy数组,其中包含10个类似高斯的数组的总和(每个数组都有一个随机生成的中心)。

我尝试使用高斯滤波器来生成单个类似高斯的数组,然后对其求和,但是我敢肯定有一种向量化的方法可以解决这个问题。即使使用num_centers=10,它的运行速度也很慢,我可能需要累加多达20个高斯。

这里有一个类似的问题,但是似乎没有一个很好的或结论性的答案,而且我不确定如何将其应用于我的问题。 Sum of Gaussians into fast Numpy?

这就是我尝试过的。

import numpy as np
from scipy.ndimage import gaussian_filter
import matplotlib.pyplot as plt


num_centers = 10               # number of Gaussians to sum
sigma = 100                    # std. dev. of each Gaussian
result = np.zeros((600, 600))


for _ in range(num_centers):

    # Pick a random coordinate within the array as the center
    center = np.random.uniform(result.shape).astype(int)

    # Make array with 1 at the center and 0 everywhere else
    temp = np.zeros_like(result)
    temp[center[0], center[1]] = 1

    # Apply filter
    gaussian = gaussian_filter(temp, sigma)

    # Add to result
    result += gaussian


# Result should look like a contour map with several hills
plt.imshow(result * 1000)        # scale up to see the coloring
plt.show()

2 个答案:

答案 0 :(得分:2)

您可以消除循环,而是在每个中心创建一个值为1的数组,然后将gaussian_filter 一次应用于此数组。所有步骤都可以矢量化。

这是一个例子。我将sigma缩小了,以便于区分中心,然后将宽度增加到800(没有特殊原因:)。

import numpy as np
from scipy.ndimage import gaussian_filter
import matplotlib.pyplot as plt


num_centers = 10
sigma = 25
size = (600, 800)

impulses = np.zeros(size)

# rows and cols are the row and column indices of the centers
# of the gaussian peaks.
np.random.seed(123456)
rows, cols = np.unravel_index(np.random.choice(impulses.size, replace=False,
                                               size=num_centers),
                              impulses.shape)
impulses[rows, cols] = 1
# or use this if you want duplicates to sum:
# np.add.at(impulses, (rows, cols), 1)

# Filter impulses to create the result.
result = gaussian_filter(impulses, sigma, mode='nearest')

plt.imshow(result)
plt.show()

这是情节:

plot

您可以尝试使用mode的{​​{1}}参数来查看哪种模式最适合您。

答案 1 :(得分:0)

我不确定如何以并行方式处理随机高斯数组的创建,因为这是花费代码最多的时间。 (我使用 var input = document.getElementById('my-text-box').value; var jsonString = JSON.stringify(input); console.log(document.getElementById('my-text-box').value); try { //message_content = JSON.parse(input); /*var message = JSON.parse(input); for (var key in message) { var keyjson = message[key]; if(typeof infoJSON !== "object"){ console.log(keyjson) } }*/ }catch (e) { error = true; log.error('Something went wrong', e) } 来确定这一点)。这是可以预期的,因为<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"> </script> <input id="my-text-box"></input> 是一个计算密集型函数。

但是,通过在一组高斯上使用timeit,我确实看到了轻微的性能提升。这是因为一次调用gaussian_filter比在循环中调用np.sum()更有效率。

示例

np.sum()