当广播NumPy数组时实际发生了什么

2024-09-22 20:22:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我在玩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的所有行(或列)不应该相等吗(就像“broadcastedx”的所有列都相等一样)?你知道吗

很明显,有些事情我不明白,我将感谢任何澄清。你知道吗


Tags: 函数numpy元素returndistdef数字sqrt
1条回答
网友
1楼 · 发布于 2024-09-22 20:22:18

我理解你的问题,你正在尝试做一个列式的平行点积。换句话说,对于向量abcd的矩阵,您需要:

[[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])

简而言之,在这种特殊情况下,您实际上希望而不是广播。你知道吗

相关问题 更多 >