在这篇文章中,我们将带领您了解使用numpy在python中进行向量化空间距离的全貌,包括numpy计算向量距离的相关情况。同时,我们还将为您介绍有关Numpy.Array在Python列表中?、Py
在这篇文章中,我们将带领您了解使用numpy在python中进行向量化空间距离的全貌,包括numpy计算向量距离的相关情况。同时,我们还将为您介绍有关Numpy.Array在Python列表中?、Python 3.x 中如何使用numpy模块进行数值计算、python numpy行向量矩阵之间的欧式距离计算、python – 仅使用NumPy计算马哈拉诺比斯距离的知识,以帮助您更好地理解这个主题。
本文目录一览:- 使用numpy在python中进行向量化空间距离(numpy计算向量距离)
- Numpy.Array在Python列表中?
- Python 3.x 中如何使用numpy模块进行数值计算
- python numpy行向量矩阵之间的欧式距离计算
- python – 仅使用NumPy计算马哈拉诺比斯距离
使用numpy在python中进行向量化空间距离(numpy计算向量距离)
我在python中有numpy数组,其中包含很多(10k +)3D顶点(坐标为[x,y,z]的向量)。我需要计算这些点所有可能的对之间的距离。
使用scipy很容易:
import scipyD = spdist.cdist(verts, verts)
但是由于引入新依赖项的项目政策,我无法使用它。
所以我想出了这个天真的代码:
def vert_dist(self, A, B): return ((B[0]-A[0])**2+(B[1]-A[1])**2+(B[2]-A[2])**2)**(1.0/2)# Pairwise distance between verts#Use SciPy, otherwise use fallbacktry: import scipy.spatial.distance as spdist D = spdist.cdist(verts, verts)except ImportError: #FIXME: This is VERY SLOW: D = np.empty((len(verts), len(verts)), dtype=np.float64) for i,v in enumerate(verts): #self.app.setStatus(_("Calculating distance %d of %d (SciPy not installed => using SLOW AF fallback method)"%(i,len(verts))), True) for j in range(i,len(verts)): D[j][i] = D[i][j] = self.vert_dist(v,verts[j])
vert_dist()计算两个顶点之间的3D距离,其余代码仅对1D数组中的顶点进行迭代,并且对于每个顶点,它都计算同一数组中彼此之间的距离并生成2D距离数组。
但这与scipy的本机C代码相比非常慢(1000倍)。我想知道我是否可以使用纯numpy加快速度。至少在某种程度上。
一些更多信息:https :
//github.com/scipy/scipy/issues/9172
顺便说一句,我已经尝试过PyPy JIT编译器,它甚至比纯python慢(10倍)。
更新:我能够加快速度,如下所示:
def vert_dist_matrix(self, verts): #FIXME: This is VERY SLOW: D = np.empty((len(verts), len(verts)), dtype=np.float64) for i,v in enumerate(verts): D[i] = D[:,i] = np.sqrt(np.sum(np.square(verts-verts[i]), axis=1)) return D
这样可以一次计算整行,从而消除了内部循环,这使处理速度相当快,但仍然比scipy慢。所以我还是看看@Divakar的解决方案
答案1
小编典典有一个eucl_dist
软件包(免责声明:我是它的作者),其中基本上包含两种方法来解决计算平方欧几里德距离的问题,该方法比的效率更高SciPy''scdist
,特别是对于大型数组(具有相当大的列数)。
我们将使用其中的一些代码sourcecode
来适应此处的问题,从而为我们提供两种方法。
方法1
继 wiki contents
,我们可以利用matrix-multiplication
一些NumPy specificimplementations
我们的第一个方法,像这样-
def pdist_squareformed_numpy(a): a_sumrows = np.einsum(''ij,ij->i'',a,a) dist = a_sumrows[:,None] + a_sumrows -2*np.dot(a,a.T) np.fill_diagonal(dist,0) return dist
方法#2
另一种方法是创建输入数组的“扩展”版本,在github源代码链接中再次进行了详细讨论,以获取我们的第二种方法,这种方法适用于较小的列,例如此处所示-
def ext_arrs(A,B, precision="float64"): nA,dim = A.shape A_ext = np.ones((nA,dim*3),dtype=precision) A_ext[:,dim:2*dim] = A A_ext[:,2*dim:] = A**2 nB = B.shape[0] B_ext = np.ones((dim*3,nB),dtype=precision) B_ext[:dim] = (B**2).T B_ext[dim:2*dim] = -2.0*B.T return A_ext, B_extdef pdist_squareformed_numpy_v2(a): A_ext, B_ext = ext_arrs(a,a) dist = A_ext.dot(B_ext) np.fill_diagonal(dist,0) return dist
请注意,这些给出了平方欧几里德距离。因此,对于实际距离,我们想使用np.sqrt()
是否需要的最终输出。
样品运行-
In [380]: np.random.seed(0) ...: a = np.random.rand(5,3)In [381]: from scipy.spatial.distance import cdistIn [382]: cdist(a,a)Out[382]: array([[0. , 0.29, 0.42, 0.2 , 0.57], [0.29, 0. , 0.58, 0.42, 0.76], [0.42, 0.58, 0. , 0.45, 0.9 ], [0.2 , 0.42, 0.45, 0. , 0.51], [0.57, 0.76, 0.9 , 0.51, 0. ]])In [383]: np.sqrt(pdist_squareformed_numpy(a))Out[383]: array([[0. , 0.29, 0.42, 0.2 , 0.57], [0.29, 0. , 0.58, 0.42, 0.76], [0.42, 0.58, 0. , 0.45, 0.9 ], [0.2 , 0.42, 0.45, 0. , 0.51], [0.57, 0.76, 0.9 , 0.51, 0. ]])In [384]: np.sqrt(pdist_squareformed_numpy_v2(a))Out[384]: array([[0. , 0.29, 0.42, 0.2 , 0.57], [0.29, 0. , 0.58, 0.42, 0.76], [0.42, 0.58, 0. , 0.45, 0.9 ], [0.2 , 0.42, 0.45, 0. , 0.51], [0.57, 0.76, 0.9 , 0.51, 0. ]])
时间10k
点-
In [385]: a = np.random.rand(10000,3)In [386]: %timeit cdist(a,a)1 loop, best of 3: 309 ms per loop# Approach #1In [388]: %timeit pdist_squareformed_numpy(a) # squared eucl distances1 loop, best of 3: 668 ms per loopIn [389]: %timeit np.sqrt(pdist_squareformed_numpy(a)) # actual eucl distances1 loop, best of 3: 812 ms per loop# Approach #2In [390]: %timeit pdist_squareformed_numpy_v2(a) # squared eucl distances1 loop, best of 3: 237 ms per loopIn [391]: %timeit np.sqrt(pdist_squareformed_numpy_v2(a)) # actual eucl distances1 loop, best of 3: 395 ms per loop
第二种方法似乎cdist
在性能上接近一种!
Numpy.Array在Python列表中?
我有一个numpy数组的列表(用作堆栈)。现在,我要检查列表中是否已存在数组。举例来说,如果是元组,我会写等同于的东西(1,1) in
[(1,1),(2,2)]
。但是,这不适用于numpy数组。np.array([1,1]) in [np.array([1,1]),np.array([2,2])]
是错误(ValueError: The truth value of an array with more than
one element is ambiguous. Use a.any() or a.all()
)。该错误消息对AFAIK无效,因为它是指直接比较数组。
我很难相信这是不可能的,但是我想我有一些缺失。
Python 3.x 中如何使用numpy模块进行数值计算
引言:
在Python的科学计算领域中,numpy是一个非常重要的模块。它提供了高性能的多维数组对象以及一系列处理这些数组的函数。通过使用numpy,我们可以简化数值计算的操作,并且获得更高的运算效率。
本文将介绍如何在Python 3.x中使用numpy模块进行数值计算,并提供相应的代码示例。
一、安装numpy模块:
在开始之前,我们需要先安装numpy模块。可以使用pip命令进行安装,执行以下命令即可:
pip install numpy
当然,你也可以使用其他适合的方式进行安装。
立即学习“Python免费学习笔记(深入)”;
二、导入numpy模块:
在开始使用numpy之前,我们需要导入numpy模块。可以使用以下代码将numpy模块导入到Python程序中:
import numpy as np
在导入时,我们通常使用别名np来表示numpy模块,这是为了方便使用numpy模块中的函数。
三、创建numpy数组:
使用numpy进行数值计算的第一步,就是创建numpy数组。numpy数组是多维数组对象,可以容纳相同类型的数据。
以下是三种常见的创建numpy数组的方式:
- 使用np.array()函数从常规Python列表或元组创建:
import numpy as np arr1 = np.array([1, 2, 3, 4, 5]) print(arr1)
输出:
[1 2 3 4 5]
- 使用np.zeros()函数创建全0数组:
import numpy as np arr2 = np.zeros((3, 4)) print(arr2)
输出:
[[0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.]]
- 使用np.ones()函数创建全1数组:
import numpy as np arr3 = np.ones((2, 3)) print(arr3)
输出:
[[1. 1. 1.] [1. 1. 1.]]
四、numpy数组的属性和操作:
numpy数组不仅仅是一个普通的数组对象,它还有一些特殊的属性和操作。以下是一些常见的numpy数组属性和操作的示例:
- 数组的形状 shape:
import numpy as np arr = np.array([[1, 2, 3], [4, 5, 6]]) print(arr.shape)
输出:
(2, 3)
- 数组的维度 ndim:
import numpy as np arr = np.array([1, 2, 3, 4]) print(arr.ndim)
输出:
1
- 数组的类型 dtype:
import numpy as np arr = np.array([1, 2, 3, 4]) print(arr.dtype)
输出:
int64
- 数组的元素个数 size:
import numpy as np arr = np.array([1, 2, 3, 4]) print(arr.size)
输出:
4
五、numpy数组的数值计算:
numpy数组提供了丰富的数值计算函数,可以用来进行各种常见的数学运算。以下是一些常见的numpy数值计算函数的示例:
- 数组的加法 np.add():
import numpy as np arr1 = np.array([1, 2, 3]) arr2 = np.array([4, 5, 6]) result = np.add(arr1, arr2) print(result)
输出:
[5 7 9]
- 数组的减法 np.subtract():
import numpy as np arr1 = np.array([4, 5, 6]) arr2 = np.array([1, 2, 3]) result = np.subtract(arr1, arr2) print(result)
输出:
[3 3 3]
- 数组的乘法 np.multiply():
import numpy as np arr1 = np.array([1, 2, 3]) arr2 = np.array([4, 5, 6]) result = np.multiply(arr1, arr2) print(result)
输出:
[4 10 18]
- 数组的除法 np.divide():
import numpy as np arr1 = np.array([4, 5, 6]) arr2 = np.array([2, 2, 2]) result = np.divide(arr1, arr2) print(result)
输出:
[2. 2.5 3. ]
以上只是一小部分numpy数值计算函数的示例,numpy还提供了其他很多常用的数值计算函数,可以根据具体需求进行使用。
结论:
通过使用numpy模块,我们可以方便地进行数值计算,并获得更高的运算效率。本文中,我们介绍了如何安装numpy模块、导入numpy模块、创建numpy数组以及进行数值计算,并提供了相应的代码示例。
通过学习和掌握numpy模块,我们能够更加高效地开展Python的科学计算工作,同时也为进一步深入学习机器学习、数据分析等领域打下了坚实的基础。
以上就是Python 3.x 中如何使用numpy模块进行数值计算的详细内容,更多请关注php中文网其它相关文章!
python numpy行向量矩阵之间的欧式距离计算
我是Numpy的新手,我想问你如何计算向量中存储的点之间的欧式距离。
假设我们有一个numpy.array,每行是一个向量,并且是一个numpy.array。我想知道是否有可能计算所有点与该单点之间的欧几里得距离并将它们存储在一个numpy.array中。
这是一个接口:
points #2d list of row-vectors
singlePoint #one row-vector
listOfDistances= procedure( points,singlePoint)
我们可以有这样的东西吗?或者是否可以使用一个命令将单个点作为其他点的列表,最后得到距离矩阵?
谢谢
python – 仅使用NumPy计算马哈拉诺比斯距离
以下代码可以使用Scipy的cdist函数正确计算相同的代码.由于此函数在我的情况下计算不必要的matix,我想要更直接的方式使用NumPy计算它.
import numpy as np from scipy.spatial.distance import cdist x = np.array([[[1,2,3,4,5],[5,6,7,8,5]],[[11,22,23,24,[25,26,27,28,5]]]) i,j,k = x.shape xx = x.reshape(i,j*k).T y = np.array([[[31,32,33,34,[35,36,37,38,[[41,42,43,44,[45,46,47,48,5]]]) yy = y.reshape(i,j*k).T results = cdist(xx,yy,'mahalanobis') results = np.diag(results) print results [ 2.28765854 2.75165028 2.75165028 2.75165028 0. 2.75165028 2.75165028 2.75165028 2.75165028 0. 0. 0. 0. 0. 0. ]
我的试用版:
VI = np.linalg.inv(np.cov(xx,yy)) print np.sqrt(np.dot(np.dot((xx-yy),VI),(xx-yy).T))
任何人都可以纠正这种方法吗?
这是它的公式:
http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.spatial.distance.mahalanobis.html#scipy.spatial.distance.mahalanobis
解决方法
X = np.vstack([xx,yy]) V = np.cov(X.T) VI = np.linalg.inv(V) print np.diag(np.sqrt(np.dot(np.dot((xx-yy),(xx-yy).T)))
输出:
[ 2.28765854 2.75165028 2.75165028 2.75165028 0. 2.75165028 2.75165028 2.75165028 2.75165028 0. 0. 0. 0. 0. 0. ]
要在没有在此隐式创建的中间数组的情况下执行此操作,您可能必须牺牲Python循环的C循环:
A = np.dot((xx-yy),VI) B = (xx-yy).T n = A.shape[0] D = np.empty(n) for i in range(n): D[i] = np.sqrt(np.sum(A[i] * B[:,i]))
编辑:实际上,使用np.einsum voodoo,你可以删除Python循环并加速它(在我的系统上,从84.3μs到2.9μs):
D = np.sqrt(np.einsum('ij,ji->i',A,B))
编辑:正如@Warren Weckesser指出的那样,einsum也可以用来取消中间A和B数组:
delta = xx - yy D = np.sqrt(np.einsum('nj,jk,nk->n',delta,VI,delta))
今天的关于使用numpy在python中进行向量化空间距离和numpy计算向量距离的分享已经结束,谢谢您的关注,如果想了解更多关于Numpy.Array在Python列表中?、Python 3.x 中如何使用numpy模块进行数值计算、python numpy行向量矩阵之间的欧式距离计算、python – 仅使用NumPy计算马哈拉诺比斯距离的相关知识,请在本站进行查询。
本文标签: