gpt4 book ai didi

python - 快速计算 python 中数组的每个元素的特征向量

转载 作者:太空宇宙 更新时间:2023-11-03 15:03:04 25 4
gpt4 key购买 nike

我想计算一组数据的特征向量(在我的实际情况下,我是多边形云)

为此我编写了这个函数:

import numpy as np

def eigen(data):
eigenvectors = []
eigenvalues = []

for d in data:
# compute covariance for each triangle
cov = np.cov(d, ddof=0, rowvar=False)

# compute eigen vectors
vals, vecs = np.linalg.eig(cov)
eigenvalues.append(vals)
eigenvectors.append(vecs)

return np.array(eigenvalues), np.array(eigenvectors)

在一些测试数据上运行:

import cProfile
triangles = np.random.random((10**4,3,3,)) # 10k 3D triangles
cProfile.run('eigen(triangles)') # 550005 function calls in 0.933 seconds

工作正常,但由于迭代循环,它变得非常慢。有没有更快的方法来计算我需要的数据而无需遍历数组?如果没有,有人可以建议加快速度的方法吗?

最佳答案

破解它!

好吧,我黑进了covariance func definition并输入规定的输入状态:ddof=0, rowvar=False 事实证明,一切都减少到只有三行 -

nC = m.shape[1]  # m is the 2D input array
X = m - m.mean(0)
out = np.dot(X.T, X)/nC

为了将其扩展到我们的 3D 数组案例,我写下了循环版本,其中这三行针对 3D 输入数组中的 2D 数组部分进行了迭代,就像这样 -

for i,d in enumerate(m):

# Using np.cov :
org_cov = np.cov(d, ddof=0, rowvar=False)

# Using earlier 2D array hacked version :
nC = m[i].shape[0]
X = m[i] - m[i].mean(0,keepdims=True)
hacked_cov = np.dot(X.T, X)/nC

提振

我们需要在那里加速最后三行。 X 在所有迭代中的计算可以通过 broadcasting -

完成
diffs = data - data.mean(1,keepdims=True)

接下来,所有迭代的点积计算可以使用 transposenp.dot 完成,但是 transpose 可以是对于这样的多维数组来说,这是一件代价高昂的事情。 np.einsum 中存在一个更好的选择,就像这样 -

cov3D = np.einsum('ijk,ijl->ikl',diffs,diffs)/data.shape[1]

使用它!

总结:

for d in data:
# compute covariance for each triangle
cov = np.cov(d, ddof=0, rowvar=False)

可以像这样预先计算:

diffs = data - data.mean(1,keepdims=True)
cov3D = np.einsum('ijk,ijl->ikl',diffs,diffs)/data.shape[1]

这些预先计算的值可以跨迭代使用来计算特征向量,就像这样 -

for i,d in enumerate(data):
# Directly use pre-computed covariances for each triangle
vals, vecs = np.linalg.eig(cov3D[i])

测试一下!

这里有一些运行时测试来评估预计算协方差结果的效果——

In [148]: def original_app(data):
...: cov = np.empty(data.shape)
...: for i,d in enumerate(data):
...: # compute covariance for each triangle
...: cov[i] = np.cov(d, ddof=0, rowvar=False)
...: return cov
...:
...: def vectorized_app(data):
...: diffs = data - data.mean(1,keepdims=True)
...: return np.einsum('ijk,ijl->ikl',diffs,diffs)/data.shape[1]
...:

In [149]: data = np.random.randint(0,10,(1000,3,3))

In [150]: np.allclose(original_app(data),vectorized_app(data))
Out[150]: True

In [151]: %timeit original_app(data)
10 loops, best of 3: 64.4 ms per loop

In [152]: %timeit vectorized_app(data)
1000 loops, best of 3: 1.14 ms per loop

In [153]: data = np.random.randint(0,10,(5000,3,3))

In [154]: np.allclose(original_app(data),vectorized_app(data))
Out[154]: True

In [155]: %timeit original_app(data)
1 loops, best of 3: 324 ms per loop

In [156]: %timeit vectorized_app(data)
100 loops, best of 3: 5.67 ms per loop

关于python - 快速计算 python 中数组的每个元素的特征向量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35756952/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com