繁体   English   中英

在 python 中分别查找列表中每个元素的转置

[英]Finding transpose of each element of list separately in python

我有一个包含 N 个项目的列表,每个 d 维度(所以本质上是一个 N xd 列表)。 对于每个项目,我想找到与自身转置的项目的乘积,因此,对于 N 个项目中的每一个,都是 x.xT。 这会给我一个 N xdxd 数组。 我怎样才能在 numpy 中有效地做到这一点。 此刻,我正在遍历每个项目并分别找到转置。

for i in range(len(mu[0])):
    current_mu = mu[i] # list of d elements
    distances = []
    for index in range(len(samples)):
        distance = np.asarray(current_mu - samples[index])[:, None] # list of d elements
        distances.append(distance * distance.T) # each becomes d x d

我可以删除第二个嵌套循环还是需要它?

您可以使用numpy.einsum如下:

import numpy as np

N,d = 10,5

mu = np.random.rand(N,d)
r = np.einsum('ni,nj->nij', mu, mu)

r.shape
(10,5,5)

与 for 循环实现相比:

def for_loop(a):
    N,d = a.shape
    r = np.zeros((N,d,d))
    for i in range(N):
        r[i] = a[i][:,None] @ a[i][None,:]

# N>d case
N,d = 1000,500
mu = np.random.rand(N,d)

%timeit np.einsum('ni,nj->nij', mu, mu)
1.29 s ± 11.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit for_loop(mu)
2.36 s ± 45.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# N<d case
N,d = 100,1000
mu = np.random.rand(N,d)

%timeit np.einsum('ni,nj->nij', mu, mu)
521 ms ± 9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit for_loop(mu)
976 ms ± 18.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

在这两种情况下,性能几乎提高了 2 倍。

@FBruzzesi 之前的回答非常有效,但如果有人更喜欢不使用 einsum 的解决方案(以及一般的完整性):

n,d=1000,500
x=np.random.randn(n,d,1)
x_einsum=x.reshape(n,d)

%timeit x * x.transpose((0,2,1))
744 ms ± 48.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit np.einsum('ni,nj->nij', x_einsum, x_einsum)
777 ms ± 18.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM