我想在Python中使用矩阵实现下面的循环:
import numpy as np
n = 5 # samples
k = 2 # inputs
m = 3 # gaussians
# X is nxk
X = np.array([[0.0, 10.0], [20.0, 30.0],[40, 50],[60,70],[80,90]])
#locations is mxk
locations = np.array([[0.01, 0.02], [0.03,0.04], [0.05, 0.06]])
dev = np.empty([n,k,m])
for samples in range(n):
for inputs in range(k):
for gaussians in range(m):
dev[samples,inputs,gaussians]=X[samples,inputs]-locations[gaussians,inputs]
output = np.empty([n,m])
for samples in range(n):
for gaussians in range(m):
output[samples,gaussians]=np.sum(dev[samples,:,gaussians]*dev[samples,:,gaussians])
我知道Numpy能够使用不同维度的数组(Broadcast)进行操作,但我不能在这里使用这个概念。请注意,我基本上做的是删除矢量样本的平均值并计算其平方范数。
答案 0 :(得分:1)
你可以像这样对你的for循环进行矢量化; dev
基本上是X
和locations
相对于第一维的外部操作,因此您可以在locations
(或X
中插入新轴,这只会影响你如何转置结果),减法会触发numpy广播并返回笛卡尔/外部减法;对于第二个,您需要将dev
与其自身相乘,并将sum
与第二维(轴= 1)相乘:
mydev = np.transpose(X - locations[:,None], (1,2,0))
(mydev == dev).all()
# True
myoutput = (mydev**2).sum(axis=1)
(myoutput == output).all()
# True
或者放在一起:
((X[:,None] - locations) ** 2).sum(axis=-1)
#array([[ 99.6005, 99.2025, 98.8061],
# [ 1298.4005, 1296.4025, 1294.4061],
# [ 4097.2005, 4093.6025, 4090.0061],
# [ 8496.0005, 8490.8025, 8485.6061],
# [ 14494.8005, 14488.0025, 14481.2061]])