使用Numpy的成对vdot

2024-09-28 03:18:42 发布

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

我试图计算一个复杂的2D数组x的成对np.vdot。所以我想要的行为是:

X = np.empty((x.shape[0], x.shape[0]), dtype='complex128')
for i in range(x.shape[0]):
    for j in range(x.shape[0]):
        X[i, j] = np.vdot(x[i], x[j])

有没有办法不用显式循环就可以做到这一点?我尝试使用来自sklearnpairwise_kernel,但它假定输入数组是实数。我也尝试过广播,但是vdot会使输入变平。在


Tags: infornprange数组sklearnkernelempty
2条回答

要将np.vdot扩展到所有行,可以使用^{},我直接借用了^{}的共轭思想,如下-

np.tensordot(np.conj(x),x,axes=(1,1))

基本上使用np.tensordot,我们指定要缩减的轴,在本例中,这是{}共轭版本的最后一个轴,以及数组本身,当应用于这两个轴上时。在

运行时测试-

让我们来计时^{} solution with ^{}和本文中提出的解决方案-

^{pr2}$
X = np.einsum('ik,jk->ij', np.conj(x), x)

相当于

^{pr2}$

^{} 取产品总数。下标'ik,jk->ij'告诉np.einsum第二个参数, np.conj(x)是一个下标为ik的数组,第三个参数x有 下标jk。因此,计算所有的乘积np.conj(x)[i,k]*x[j,k]ijk。求和取重复下标k,因此 保留ij,它们将成为结果数组的下标。在


例如

import numpy as np

N, M = 10, 20
a = np.random.random((N,M))
b = np.random.random((N,M))
x = a + b*1j

def orig(x):
    X = np.empty((x.shape[0], x.shape[0]), dtype='complex128')
    for i in range(x.shape[0]):
        for j in range(x.shape[0]):
            X[i, j] = np.vdot(x[i], x[j])
    return X

def alt(x):
    return np.einsum('ik,jk->ij', np.conj(x), x)

assert np.allclose(orig(x), alt(x))

In [307]: %timeit orig(x)
10000 loops, best of 3: 143 µs per loop

In [308]: %timeit alt(x)
100000 loops, best of 3: 8.63 µs per loop

相关问题 更多 >

    热门问题