我目前正在尝试填充矩阵K,其中矩阵中的每个条目只是应用于数组x的两个条目的函数。目前,我正在使用最明显的方法,使用双for循环一次运行一行和列:
K = np.zeros((x.shape[0],x.shape[0]), dtype=np.float32)
for i in range(x.shape[0]):
for j in range(x.shape[0]):
K[i,j] = f(x[i],x[j])
虽然这可以很好地工作,但得到的矩阵是一个10,000 × 10,000的矩阵,需要很长时间来计算。我想知道是否有一种更有效的方法来做到这一点内置到NumPy?
编辑:这里讨论的函数是高斯核函数:
def gaussian(a,b,sigma):
vec = a-b
return np.exp(- np.dot(vec,vec)/(2*sigma**2))
中,我在计算矩阵之前预先设置了sigma。数组x是形状为(10000,8)的数组,因此高斯函数中的标量积是两个8维向量之间的乘积。
您可以将单个for
环路与广播一起使用。这需要改变gaussian
函数的实现以接受2D输入:
def gaussian(a,b,sigma):
vec = a-b
return np.exp(- np.sum(vec**2, axis=-1)/(2*sigma**2))
K = np.zeros((x.shape[0],x.shape[0]), dtype=np.float32)
for i in range(x.shape[0]):
K[i] = gaussian(x[i:i+1], x)
理论上你可以做到这一点,即使没有任何for
循环,再次使用广播,但这里一个大小为len(x)**2 * x.shape[1]
的中间数组将被创建,这可能会耗尽你的数组大小的内存:
K = gaussian(x[None, :, :], x[:, None, :])