我正在和NumPy一起玩,我写了简单的功能
> def euclid_dist(x, y):
... return sqrt((x-y).transpose().dot(x-y))
但现在我尝试
> x = arange(1,4).reshape(3,1)
> y = array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]]).transpose()
> z = euclid_dist(x, y)
> z
array([[ 0. , 0. , 0. , 0. ],
[ 0. , 5.19615242, 7.34846923, 9. ],
[ 0. , 7.34846923, 10.39230485, 12.72792206],
[ 0. , 9. , 12.72792206, 15.58845727]])
好的......所以,对角线上的数字是我想要的东西,但其余的呢?刚刚发生了什么?
据我所知,x
被广播,因此它变成'
array([[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3]])
但之后会发生什么?这显然不是元素操作。但是,如果它将函数应用于x和y的每对列,那么z
的所有行(或列)都不应该相等(因为'广播x
'的所有列都相等)?
显然有一些我不理解的东西,我将不胜感激任何澄清。
答案 0 :(得分:2)
正如我理解你的问题,你正试图做一个列式并行点产品。换句话说,对于向量a
,b
,c
和d
的矩阵,您想要这样做:
[[a1, b1, c1, d1],
[a2, b2, c2, d2],
[a3, b3, c3, d3]]
对此:
[a1 * a1 + a2 * a2 + a3 * a3,
b1 * b1 + b2 * b2 + b3 * b3,
c1 * c1 + c2 * c2 + c3 * c3,
d1 * d1 + d2 * d2 + d3 * d3]
事实上,你对广播的理解看起来很好。它dot
不能按预期的方式工作 - 它会进行矩阵乘法运算。所以你得到以下结果(取决于你的转置方式):
>>> sqrt((x - y).T.dot(x - y))
array([[ 11.22497216, 11.22497216, 11.22497216],
[ 11.22497216, 11.22497216, 11.22497216],
[ 11.22497216, 11.22497216, 11.22497216]])
>>> sqrt((x - y).dot((x - y).T))
array([[ 0. , 0. , 0. , 0. ],
[ 0. , 5.19615242, 7.34846923, 9. ],
[ 0. , 7.34846923, 10.39230485, 12.72792206],
[ 0. , 9. , 12.72792206, 15.58845727]])
第二个结果的对角线是你正在寻找的,但是全矩阵乘法会做太多额外的工作。以下是我通常只对角线的说法,粗略地说:
>>> sqrt(((x - y) * (x - y)).sum(axis=1))
array([ 0. , 5.19615242, 10.39230485, 15.58845727])
简而言之,在这种特殊情况下,您实际上希望不进行广播。