在所有扩展上生成内核密度的数组/矩阵

Generate array / matrix of kernel density over all extension

我想将核密度函数的所有值提取到矩阵(形状为 ymax、xmax 的 numpy 数组)。用 seaborn 绘制核密度非常容易:

import matplotlib.pyplot as plt 
import numpy as np
import seaborn as sns
import stats, random


x = random.sample(range(2000, 4500), 1000)
y = random.sample(range(0, 2500), 1000)

sns.kdeplot(x,y)

而且提取指定位置的密度值也很容易:

values = np.array(list(zip(x, y)))
kernel = stats.gaussian_kde(values.T)

# Extracting kernel value at [xcoords],[ycoords] 
kernel([[2500,3700,4500],[500,2000,2500]])

array([3.09998436e-07, 4.63280866e-07, 1.56687705e-09])

问题是,如何将所有可能的值提取到矩阵中(给定扩展)?我想用它做矩阵计算。如果我尝试使用以前的方法并将每个像素的坐标都给它,那就太慢了。

#Fast      (extracting kernel density value at every 100 xy points)
kernel(np.array(list(
           itertools.product(
                range(0,1000,100),
                range(0,1000,100))
           )).T)

# Slow     (extracting kernel density value at all possible xy points)
kernel(np.array(list(
           itertools.product(
                 range(0,1000),
                 range(0,1000))
           )).T)

这很慢,因为 itertools.product 是一个 可迭代对象,它会产生数百万个需要解码的纯 Python 对象(整数和元组)由 Numpy 翻译成原生整数。您可以直接使用 Numpy 来高效地生成这样的数组:

rng = np.arange(1000)
x = np.repeat(rng, 1000)
y = np.tile(rng, 1000)
idx = np.hstack((x[:, None], y[:, None]))
kernel(idx)

索引的生成在我的机器上快了 80 倍。