pairwise distances between list of strings rows within a dataframe column(数据帧列中字符串行的列表之间的成对距离)
问题描述
我有一个数据帧,其中有一列字符串ID列表。(见下文)。 我想在所有行之间的所有成对距离之间创建距离矩阵 (例如,如果是10行,则它是10x10矩阵)。 这些行是ID列表,所以我不确定如何使用像pdist这样的东西。
这些值是字符串ID。就像字符串名称
ids
0 [58545-19, 462423-43, 277581-25]
1 [0]
2 [454950-82, 433701-46, 228790-63, 266250-52, 458759-98, 152986-78, 222217-39, 433515-16, 265589-83, 439403-23, 277892-38, 223497-19, 224072-83, 461887-57, 436147-12, 227479-78, 228893-32, 279415-18, 439426-27, 437742-46, 438156-73, 438458-68, 277898-05, 438675-76, 454658-95, 431222-77, 462579-94, 434939-86, 222211-09, 178215-13, 459566-11, 463200-04, 439278-94, 459505-18, 399139-66, 455735-62, 327382-03, 439040-62, 233779-51, 431387-38, 438589-72, 437892-49, 458178-76]
3 [431380-63]
4 [442539-01, 434388-16, 454950-82, 463197-61, 228893-32, 464322-07, 462579-94, 438781-51, 437273-11, 265395-79, 463560-76, 462525-31, 439426-27, 438458-68, 464300-38, 442676-80]
5 [234729-10, 435926-98, 416670-04, 179514-28]
6 [0]
7 [0]
8 [267726-25, 235217-71, 227314-72, 185293-18, 434447-56, 170271-19, 454661-20]
9 [0]
推荐答案
以下是使用scipy.spatial.distance.pdist
函数计算成对距离的解决方案(请参阅末尾的完整代码)。
分步
自定义Jaccard函数
虽然scipy.spatial.distance
有一个jaccard
方法,但这个方法是针对布尔数组的。我们将需要定义一个自定义函数(使用jaccard distance:1-intersection/union
的定义):
def jaccard(u, v):
u,v = set(u[0]), set(v[0]) # pdist will pass 2D data [[a,b,c]], so we need to slice
return 1-len(u.intersection(v))/len(u.union(v))
然后我们将其应用于我们的DataFrame列。
警告:pdist
需要多维数组作为输入(Series不起作用),因此我们需要将该列切片为DataFrame(df[['ids']]
)。此外,直接将该函数作为metric
传递会导致错误,因为该函数未被矢量化(请参阅下面关于这一点的注释),因此我们需要将其包装在lambda中。
pdist(df[['ids']], metric=lambda u,v: jaccard(u,v))
如上所述,也可以传递矢量化函数。为此,我们可以使用numpy.vectorize
。请注意,该函数与以前略有不同。这里我们不对传递的值的第一个元素进行切片,因为它已经是一维的。
def jaccard(u, v):
u,v = set(u), set(v)
return 1-len(u.intersection(v))/len(u.union(v))
pdist(df[['ids']], metric=np.vectorize(jaccard))
Nb。对提供的数据集进行的快速测试表明,矢量化方法实际上比lambda慢。
以2D形式输出
最后,我们使用scipy.spatial.distance.squareform
和pandas.DataFrame
构造函数将输出转换回矩阵:
pd.DataFrame(squareform(pdist(df[['ids']], metric=lambda u,v: jaccard(u,v))))
示例(完整代码)
让我们从以下输入开始:
df = pd.DataFrame([[['58545-19', '462423-43', '277581-25']],
[['0']],
[['454950-82', '433701-46', '228790-63', '266250-52', '458759-98', '152986-78', '222217-39', '433515-16', '265589-83', '439403-23', '277892-38', '223497-19', '224072-83', '461887-57', '436147-12', '227479-78', '228893-32', '279415-18', '439426-27', '437742-46', '438156-73', '438458-68', '277898-05', '438675-76', '454658-95', '431222-77', '462579-94', '434939-86', '222211-09', '178215-13', '459566-11', '463200-04', '439278-94', '459505-18', '399139-66', '455735-62', '327382-03', '439040-62', '233779-51', '431387-38', '438589-72', '437892-49', '458178-76']],
[['431380-63']],
[['442539-01', '434388-16', '454950-82', '463197-61', '228893-32', '464322-07', '462579-94', '438781-51', '437273-11', '265395-79', '463560-76', '462525-31', '439426-27', '438458-68', '464300-38', '442676-80']],
[['234729-10', '435926-98', '416670-04', '179514-28']],
[['0']],
[['0']],
[['267726-25', '235217-71', '227314-72', '185293-18', '434447-56', '170271-19', '454661-20']],
[['0']],
], columns=['ids'])
from scipy.spatial.distance import pdist, squareform
def jaccard(u, v):
u,v = set(u[0]), set(v[0])
return 1-len(u.intersection(v))/len(u.union(v))
pd.DataFrame(squareform(pdist(df[['ids']], metric=lambda u,v: jaccard(u,v))))
输出:
0 1 2 3 4 5 6 7 8 9
0 0.0 1.0 1.000000 1.0 1.000000 1.0 1.0 1.0 1.0 1.0
1 1.0 0.0 1.000000 1.0 1.000000 1.0 0.0 0.0 1.0 0.0
2 1.0 1.0 0.000000 1.0 0.907407 1.0 1.0 1.0 1.0 1.0
3 1.0 1.0 1.000000 0.0 1.000000 1.0 1.0 1.0 1.0 1.0
4 1.0 1.0 0.907407 1.0 0.000000 1.0 1.0 1.0 1.0 1.0
5 1.0 1.0 1.000000 1.0 1.000000 0.0 1.0 1.0 1.0 1.0
6 1.0 0.0 1.000000 1.0 1.000000 1.0 0.0 0.0 1.0 0.0
7 1.0 0.0 1.000000 1.0 1.000000 1.0 0.0 0.0 1.0 0.0
8 1.0 1.0 1.000000 1.0 1.000000 1.0 1.0 1.0 0.0 1.0
9 1.0 0.0 1.000000 1.0 1.000000 1.0 0.0 0.0 1.0 0.0
以下是提供的数据集的距离的图形表示(白色=更远):
这篇关于数据帧列中字符串行的列表之间的成对距离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:数据帧列中字符串行的列表之间的成对距离
基础教程推荐
- 如何在Python中绘制多元函数? 2022-01-01
- 如何在 Python 中检测文件是否为二进制(非文本)文 2022-01-01
- 哪些 Python 包提供独立的事件系统? 2022-01-01
- 使用 Google App Engine (Python) 将文件上传到 Google Cloud Storage 2022-01-01
- Python 的 List 是如何实现的? 2022-01-01
- 使用Python匹配Stata加权xtil命令的确定方法? 2022-01-01
- 合并具有多索引的两个数据帧 2022-01-01
- 将 YAML 文件转换为 python dict 2022-01-01
- 症状类型错误:无法确定关系的真值 2022-01-01
- 使 Python 脚本在 Windows 上运行而不指定“.py";延期 2022-01-01