# python 各类距离公式实现

• 闵可夫斯基距离(Minkowski Distance)
• 欧氏距离(Euclidean Distance)
• 曼哈顿距离(Manhattan Distance)
• 切比雪夫距离(Chebyshev Distance)
• 夹角余弦(Cosine)
• 汉明距离(Hamming distance)
• 杰卡德相似系数(Jaccard similarity coefficient)
• 编辑距离（Edit Distance）
• 标准化欧氏距离 (Standardized Euclidean distance )
• 马氏距离(Mahalanobis Distance)
• 皮尔逊相关系数（Pearson correlation）
• 布雷柯蒂斯距离(Bray Curtis Distance)

## 1. 闵可夫斯基距离(Minkowski Distance)

(1)闵氏距离的定义:

(2)闵氏距离的缺点

python中的实现：

```# -*- coding:utf-8 -*-
import numpy as np
x=np.random.random(10)
y=np.random.random(10)

#方法一：根据公式求解,p=2
d1=np.sqrt(np.sum(np.square(x-y)))
print('d1:',d1)

#方法二：根据scipy库求解
from scipy.spatial.distance import pdist
X=np.vstack([x,y])
d2=pdist(X,'minkowski',p=2)[0]
print('d2:',d2)```

## 2.欧氏距离(Euclidean Distance)

(4) python实现欧式距离公式的：

```# -*- coding: utf-8 -*-
from numpy import *

vector1 = mat([1,2,3])
vector2 = mat([4,5,6])
print (sqrt((vector1-vector2)*((vector1-vector2).T)))

import numpy as np

x = np.random.random(10)
y = np.random.random(10)
# solution1
dist1 = np.linalg.norm(x - y)
# solution2
dist2 = np.sqrt(np.sum(np.square(x - y)))
print('x', x)
print('y', y)
print('dist1:', dist1)
print('dist2:', dist2)

# solution3
from scipy.spatial.distance import pdist

X=np.vstack([x,y])
d2=pdist(X)[0]
print('d2:',d2)```

## 3.曼哈顿距离(Manhattan Distance)

(3)python实现曼哈顿距离：

```# -*- coding: utf-8 -*-
from numpy import *

vector1 = mat([1,2,3])
vector2 = mat([4,5,6])
print (sum(abs(vector1-vector2)))

import numpy as np

x=np.random.random(10)
y=np.random.random(10)
#方法一：根据公式求解
d1=np.sum(np.abs(x-y))
print('d1:',d1)

#方法二：根据scipy库求解
from scipy.spatial.distance import pdist

X=np.vstack([x,y])
d2=pdist(X,'cityblock')[0]
print('d2:',d2)```

## 4.切比雪夫距离(Chebyshev Distance)

(3) Python实现切比雪夫距离：

```# -*- coding: utf-8 -*-
from numpy import *

vector1 = mat([1,2,3])
vector2 = mat([4,7,5])
print (abs(vector1-vector2).max())

import numpy as np

x=np.random.random(10)
y=np.random.random(10)
#方法一：根据公式求解
d1=np.max(np.abs(x-y))
print('d1:',d1)

#方法二：根据scipy库求解
from scipy.spatial.distance import pdist

X=np.vstack([x,y])
d2=pdist(X,'chebyshev')[0]
print('d2:',d2)```

## 5. 夹角余弦(Cosine)

(1)在二维空间中向量A(x1,y1)与向量B(x2,y2)的夹角余弦公式：

(2) 两个n维样本点A (x11,x12,…,x1n)与 B(x21,x22,…,x2n)的夹角余弦 类似的，对于两个n维样本点A(x11,x12,…,x1n)与 B(x21,x22,…,x2n)，可以使用类似于夹角余弦的概念来衡量它们间的相似程度。

(3)python实现夹角余弦

```# -*- coding: utf-8 -*-
import numpy as np
from scipy.spatial.distance import pdist

'''
x: [0.05627679 0.80556938 0.48002662 0.24378563 0.75763754 0.15353348
0.54491664 0.1775408  0.50011986 0.55041845]
y: [0.50068882 0.12200178 0.79041352 0.07332715 0.017892   0.57880032
0.56707591 0.48390753 0.631051   0.20035466]
'''
x = np.random.random(10)
y = np.random.random(10)
# solution1
dist1 = 1 - np.dot(x, y) / (np.linalg.norm(x) * np.linalg.norm(y))
# solution2
dist2 = pdist(np.vstack([x, y]), 'cosine')[0]
print('x', x)
print('y', y)
print('dist1:', dist1)
print('dist2:', dist2)```

## 6. 汉明距离(Hamming distance)

(1)汉明距离的定义

(2) python实现汉明距离：

```# -*- coding: utf-8 -*-
from numpy import *

matV = mat([[1,1,0,1,0,1,0,0,1],[0,1,1,0,0,0,1,1,1]])
smstr = nonzero(matV[0]-matV[1])
print(shape(smstr[0])[0])

import numpy as np
from scipy.spatial.distance import pdist

x=np.random.random(10)>0.5
y=np.random.random(10)>0.5
x=np.asarray(x,np.int32)
y=np.asarray(y,np.int32)
#方法一：根据公式求解
d1=np.mean(x!=y)
print('d1:', d1)

#方法二：根据scipy库求解
X=np.vstack([x,y])
d2=pdist(X,'hamming')[0]
print('d2:', d2)```

## 7. 杰卡德相似系数(Jaccard similarity coefficient)

(1) 杰卡德相似系数

(2) 杰卡德距离

(3) 杰卡德相似系数与杰卡德距离的应用

P：样本A与B都是1的维度的个数

q：样本A是1，样本B是0的维度的个数

r：样本A是0，样本B是1的维度的个数

s：样本A与B都是0的维度的个数

(4) Python实现杰卡德距离：

```# -*- coding: utf-8 -*-
from numpy import *
from scipy.spatial.distance import pdist # 导入scipy距离公式

matV = mat([[1,1,0,1,0,1,0,0,1],[0,1,1,0,0,0,1,1,1]])
print ("dist.jaccard:", pdist(matV,'jaccard'))

import numpy as np
from scipy.spatial.distance import pdist

x = np.random.random(10) > 0.5
y = np.random.random(10) > 0.5
x = np.asarray(x, np.int32)
y = np.asarray(y, np.int32)
# 方法一：根据公式求解
up = np.double(np.bitwise_and((x != y), np.bitwise_or(x != 0, y != 0)).sum())
down = np.double(np.bitwise_or(x != 0, y != 0).sum())
d1 = (up / down)
print('d1:', d1)
# 方法二：根据scipy库求解
X = np.vstack([x, y])
d2 = pdist(X, 'jaccard')[0]
print('d2:', d2)```

## 8. 编辑距离（Edit Distance）

sitten （k→s）

sittin （e→i）

sitting （→g）

Python中的Levenshtein包可以方便的计算编辑距离

```# -*- coding:utf-8 -*-
import Levenshtein
texta = '艾伦 图灵传'
textb = '艾伦•图灵传'
print Levenshtein.distance(texta,textb)```

```# -*- coding:utf-8 -*-
import Levenshtein
texta = u'艾伦 图灵传'
textb = u'艾伦•图灵传'
print Levenshtein.distance(texta,textb)```

`Levenshtein.distance(str1, str2)`

`Levenshtein.hamming(str1, str2)`

`Levenshtein.ratio(str1, str2)`

`Levenshtein.jaro(s1, s2)`

`Levenshtein.jaro_winkler(s1, s2)`

dj是两个字符串的Jaro Distance

ι是前缀的相同的长度，但是规定最大为4

p则是调整分数的常数，规定不能超过25，不然可能出现dw大于1的情况，Winkler将这个常数定义为0.1

`dw = 0.944 + (3 * 0.1(1 − 0.944)) = 0.961`

## 9. 标准化欧氏距离 (Standardized Euclidean distance )

(1)标准欧氏距离的定义

python中的实现：

```# -*- coding: utf-8 -*-
import numpy as np
x=np.random.random(10)
y=np.random.random(10)

X=np.vstack([x,y])

#方法一：根据公式求解
sk=np.var(X,axis=0,ddof=1)
d1=np.sqrt(((x - y) ** 2 /sk).sum())
print('d1:',d1)

#方法二：根据scipy库求解
from scipy.spatial.distance import pdist
d2=pdist(X,'seuclidean')[0]
print('d2:',d2)```

## 10. 马氏距离(Mahalanobis Distance)

（1）马氏距离定义 有M个样本向量X1~Xm，协方差矩阵记为S，均值记为向量μ，则其中样本向量X到u的马氏距离表示为：

python 中的实现：

```# -*- coding: utf-8 -*-
import numpy as np

x = np.random.random(10)
y = np.random.random(10)

# 马氏距离要求样本数要大于维数，否则无法求协方差矩阵
# 此处进行转置，表示10个样本，每个样本2维
X = np.vstack([x, y])
XT = X.T

# 方法一：根据公式求解
S = np.cov(X)  # 两个维度之间协方差矩阵
SI = np.linalg.inv(S)  # 协方差矩阵的逆矩阵
# 马氏距离计算两个样本之间的距离，此处共有10个样本，两两组合，共有45个距离。
n = XT.shape[0]
d1 = []
for i in range(0, n):
for j in range(i + 1, n):
delta = XT[i] - XT[j]
d = np.sqrt(np.dot(np.dot(delta, SI), delta.T))
d1.append(d)
print('d1:', d1)

# 方法二：根据scipy库求解
from scipy.spatial.distance import pdist

d2 = pdist(XT, 'mahalanobis')
print('d2:',d2)```

1）马氏距离的计算是建立在总体样本的基础上的，这一点可以从上述协方差矩阵的解释中可以得出，也就是说，如果拿同样的两个样本，放入两个不同的总体中，最后计算得出的两个样本间的马氏距离通常是不相同的，除非这两个总体的协方差矩阵碰巧相同；

2）在计算马氏距离过程中，要求总体样本数大于样本的维数，否则得到的总体样本协方差矩阵逆矩阵不存在，这种情况下，用欧式距离计算即可。

3）还有一种情况，满足了条件总体样本数大于样本的维数，但是协方差矩阵的逆矩阵仍然不存在，比如三个样本点（3，4），（5，6）和（7，8），这种情况是因为这三个样本在其所处的二维空间平面内共线。这种情况下，也采用欧式距离计算。

4）在实际应用中“总体样本数大于样本的维数”这个条件是很容易满足的，而所有样本点出现3）中所描述的情况是很少出现的，所以在绝大多数情况下，马氏距离是可以顺利计算的，但是马氏距离的计算是不稳定的，不稳定的来源是协方差矩阵，这也是马氏距离与欧式距离的最大差异之处。

## 11. 皮尔逊相关系数（Pearson correlation）

(1) 皮尔逊相关系数的定义

```# -*- coding: utf-8 -*-
import numpy as np

x=np.random.random(10)
y=np.random.random(10)

#方法一：根据公式求解
x_=x-np.mean(x)
y_=y-np.mean(y)
d1=np.dot(x_,y_)/(np.linalg.norm(x_)*np.linalg.norm(y_))
print('d1:', d1)

#方法二：根据numpy库求解
X=np.vstack([x,y])
d2=np.corrcoef(X)[0][1]
print('d2:', d2)```

## 12. 布雷柯蒂斯距离(Bray Curtis Distance)

Bray Curtis距离主要用于生态学和环境科学，计算坐标之间的距离。该距离取值在[0,1]之间。它也可以用来计算样本之间的差异。

```# -*- coding: utf-8 -*-
import numpy as np
from scipy.spatial.distance import pdist

x = np.array([11, 0, 7, 8, 0])
y = np.array([24, 37, 5, 18, 1])
# 方法一：根据公式求解
up = np.sum(np.abs(y - x))
down = np.sum(x) + np.sum(y)
d1 = (up / down)
print('d1:', d1)
# 方法二：根据scipy库求解
X = np.vstack([x, y])
d2 = pdist(X, 'braycurtis')[0]
print('d2:', d2)```

0 条评论

• ### Numpy.random.seed()和numpy.random.RandomState()用法

设置seed（）里的数字就相当于设置了一个盛有随机数的“聚宝盆”，一个数字代表一个“聚宝盆”，当我们在seed（）的括号里设置相同的seed，“聚宝盆”就是一样...

• ### 科学计算工具Numpy

Numpy：提供了一个在Python中做科学计算的基础库，重在数值计算，主要用于多维数组（矩阵）处理的库。用来存储和处理大型矩阵，比Python自身的嵌套列表结...

• ### HanLP 分词

版权声明：本文为博主原创文章，遵循 CC 4.0 BY-SA 版权协议，转载请附上原文出处链接和本声明。

• ### TCP协议细节学习

TCP协议中可选的MSS（Maximum Segment Size，最大报文长度））参数，一般使用MTU代替，值为1460。这个值是怎么来的呢？ Maximu...

• ### 【小家Spring】Spring事务相关的基础类打点(spring-jdbc和spring-tx两个jar)，着重讲解AnnotationTransactionAttributeSource

本篇博文定位为为事务相关的其余博文的工具博文，属于Spring事务相关的基础类的打点、扫盲篇。

• ### Linux生成随机密码的2种常用办法

日常工作中经常临时用密码，因此有了生成随机密码的需求。日常工作中经常临时用密码，因此有了生成随机密码的需求。日常工作中经常临时用密码，因此有了生成随机密码的需求...

• ### 算法集锦（21） | 自动驾驶 |汽车转向角控制算法

自从十多前年Darpa的Grand Challenge竞赛开始，自动驾驶汽车技术不断得以发展，尤其近年来随着深度学习技术的出现，技术进步越来越快。自动驾驶汽车的...

• ### 谷歌开放TPU应对英伟达GPU挑战

谷歌宣布将以“有限数量”向谷歌云客户开放张量处理器（Tensor Processing Unit，简称TPU）服务，按时收费，每小时成本6.50美元。 谷歌宣布...

• ### 【深度学习】自动驾驶：使用深度学习预测汽车的转向角度

近年来，特别是在10年前Darpa挑战赛成功之后，全自动驾驶汽车的开发速度大大加快。自动驾驶汽车由许多部件组成，其中最关键的部件是驱动它的传感器和人工智能软件。...