使用自定义相似度函数创建距离矩阵
Create distance matrix using a custom similarity function
我有一个如下所示的数据框:
data = pd.DataFrame({'id':[1,1,1,2,2,2,3,3,3],
'age':[20, 21,18,54,23,11, 19, 18,12],
'experience':[5,4,3,8,2,11,2,8,6]},columns=['id','age','experience'])
id age experience
0 1 20 5
1 1 21 4
2 1 18 3
3 2 54 8
4 2 23 2
5 2 11 11
6 3 19 2
7 3 18 8
8 3 12 6
我正在使用一个名为 dtw_path 的自定义距离函数来计算元组之间的距离。作为一个复杂的过程,我不会深入探讨该函数如何准确计算距离,但它只是输出元组之间的标量距离值。
元组按以下方式形成:
data['age_exp'] = data[['age', 'experience']].apply(tuple, axis=1)
id age experience age_exp
0 1 20 5 (20, 5)
1 1 21 4 (21, 4)
2 1 18 3 (18, 3)
3 2 54 8 (54, 8)
4 2 23 2 (23, 2)
5 2 11 11 (11, 11)
6 3 19 2 (19, 2)
7 3 18 8 (18, 8)
8 3 12 6 (12, 6)
所以对于上面的数据框,如果我需要计算 id 1 和 id 2 之间的距离,我将计算距离如下:
data1 = data[data['id']==1]
data1 = np.array(data1['age_exp'].tolist())
data1
array([[20, 5],
[21, 4],
[18, 3]])
data2 = data[data['id']==2]
data2 = np.array(data2['age_exp'].tolist())
data2
array([[54, 8],
[23, 2],
[11, 11]])
dtw_path(data1,data2)[1]
1.5
我需要帮助的是如何遍历数据框并为 id 列创建距离矩阵,即类似这样的东西
1 2 3
1 0 1.5 2
2 1.5 0 2.3
3 2 2.3 0
你的问题中不清楚 dtw_path
是什么。我在这里使用 tslearn.metrics.dtw_path
,这给了我不同的结果。然而,道理应该是一样的。
让我们首先对原始数据框进行一些整形:
data2 = (data.groupby('id')
.apply(lambda x: np.array(list(zip(x['age'], x['experience']))))
).to_frame()
0
id
1 [[20, 5], [21, 4], [18, 3]]
2 [[54, 8], [23, 2], [11, 11]]
3 [[19, 2], [18, 8], [12, 6]]
注意。下一步需要二维(DataFrame),因此.to_frame()
然后,使用 scipy.spatial.distance.pdist
that can take an arbitrary distance function using the parameter metric
and keep only the second element of the output. Finally, reshape the output as a square matrix using scipy.spatial.distance.squareform
:
应用您的 dtw_path
函数
squareform(pdist(data2, metric=lambda x,y: dtw_path(x[0], y[0])[1]))
输出:
array([[ 0. , 35.86084215, 8.94427191],
[35.86084215, 0. , 36.7151195 ],
[ 8.94427191, 36.7151195 , 0. ]])
我有一个如下所示的数据框:
data = pd.DataFrame({'id':[1,1,1,2,2,2,3,3,3],
'age':[20, 21,18,54,23,11, 19, 18,12],
'experience':[5,4,3,8,2,11,2,8,6]},columns=['id','age','experience'])
id age experience
0 1 20 5
1 1 21 4
2 1 18 3
3 2 54 8
4 2 23 2
5 2 11 11
6 3 19 2
7 3 18 8
8 3 12 6
我正在使用一个名为 dtw_path 的自定义距离函数来计算元组之间的距离。作为一个复杂的过程,我不会深入探讨该函数如何准确计算距离,但它只是输出元组之间的标量距离值。
元组按以下方式形成:
data['age_exp'] = data[['age', 'experience']].apply(tuple, axis=1)
id age experience age_exp
0 1 20 5 (20, 5)
1 1 21 4 (21, 4)
2 1 18 3 (18, 3)
3 2 54 8 (54, 8)
4 2 23 2 (23, 2)
5 2 11 11 (11, 11)
6 3 19 2 (19, 2)
7 3 18 8 (18, 8)
8 3 12 6 (12, 6)
所以对于上面的数据框,如果我需要计算 id 1 和 id 2 之间的距离,我将计算距离如下:
data1 = data[data['id']==1]
data1 = np.array(data1['age_exp'].tolist())
data1
array([[20, 5],
[21, 4],
[18, 3]])
data2 = data[data['id']==2]
data2 = np.array(data2['age_exp'].tolist())
data2
array([[54, 8],
[23, 2],
[11, 11]])
dtw_path(data1,data2)[1]
1.5
我需要帮助的是如何遍历数据框并为 id 列创建距离矩阵,即类似这样的东西
1 2 3
1 0 1.5 2
2 1.5 0 2.3
3 2 2.3 0
你的问题中不清楚 dtw_path
是什么。我在这里使用 tslearn.metrics.dtw_path
,这给了我不同的结果。然而,道理应该是一样的。
让我们首先对原始数据框进行一些整形:
data2 = (data.groupby('id')
.apply(lambda x: np.array(list(zip(x['age'], x['experience']))))
).to_frame()
0
id
1 [[20, 5], [21, 4], [18, 3]]
2 [[54, 8], [23, 2], [11, 11]]
3 [[19, 2], [18, 8], [12, 6]]
注意。下一步需要二维(DataFrame),因此.to_frame()
然后,使用 scipy.spatial.distance.pdist
that can take an arbitrary distance function using the parameter metric
and keep only the second element of the output. Finally, reshape the output as a square matrix using scipy.spatial.distance.squareform
:
dtw_path
函数
squareform(pdist(data2, metric=lambda x,y: dtw_path(x[0], y[0])[1]))
输出:
array([[ 0. , 35.86084215, 8.94427191],
[35.86084215, 0. , 36.7151195 ],
[ 8.94427191, 36.7151195 , 0. ]])