根据另一个数据框中的标签以最小距离标记数据框中的一行 - Python
Labeling a row in a dataframe according to a label in another dataframe with minimum distance - Python
如果有如下两个dataframes。
df1 =
A B C Label
1.5 2 1.5 1
2.5 3 2.5 2
3.5 4 3.5 3
和 df2 =
A B C
2 2 2
3 3 3
4 4 4
3 3 3
我想将标签添加到行与行之间的距离最小的每一行。那将是:
A B C Label
3 3 3 2
2 2 2 1
4 4 4 3
3 3 3 2
我尝试了什么:
final_label = []
final_label.append(min(distance.euclidean(df2.iloc[i,:],
df1.iloc[j,:]) for j in len(df1) for i in len(df2))
注意:重要的是不要丢失 df2 的顺序。
您可以使用 numpy 的广播来计算每对之间的欧氏距离,并找到 argmin
的最小值。
v = ((df1.iloc[:, :-1].values[:, None] - df2.values) ** 2).sum(-1).argmin(0)
df2.assign(Label=df1.Label.iloc[v].values)
A B C Label
0 2 2 2 1
1 3 3 3 2
2 4 4 4 3
3 3 3 3 2
scipy.spatial.distance.cdist
+ np.where
ary=scipy.spatial.distance.cdist(df1[['A', 'B', 'C']], df2[['A', 'B', 'C']], metric='euclidean')
order=np.where(ary==ary.min(1)[:,None])
df2['New']=df1.reindex(order[1]).Label.values
df2
Out[612]:
A B C Label New
0 3 3 3 2 2
1 2 2 2 1 1
2 4 4 4 3 3
编辑:通过使用 cold 的 argmin()
ary = scipy.spatial.distance.cdist(df2[['A', 'B', 'C']], df1[['A', 'B', 'C']], metric='euclidean')
df2['New']=df1.reindex(ary.argmin(1)).Label.values
df2
Out[659]:
A B C Label New
0 3 3 3 2 2
1 2 2 2 1 1
2 4 4 4 3 3
3 3 3 3 3 2
如果有如下两个dataframes。
df1 =
A B C Label
1.5 2 1.5 1
2.5 3 2.5 2
3.5 4 3.5 3
和 df2 =
A B C
2 2 2
3 3 3
4 4 4
3 3 3
我想将标签添加到行与行之间的距离最小的每一行。那将是:
A B C Label
3 3 3 2
2 2 2 1
4 4 4 3
3 3 3 2
我尝试了什么:
final_label = []
final_label.append(min(distance.euclidean(df2.iloc[i,:],
df1.iloc[j,:]) for j in len(df1) for i in len(df2))
注意:重要的是不要丢失 df2 的顺序。
您可以使用 numpy 的广播来计算每对之间的欧氏距离,并找到 argmin
的最小值。
v = ((df1.iloc[:, :-1].values[:, None] - df2.values) ** 2).sum(-1).argmin(0)
df2.assign(Label=df1.Label.iloc[v].values)
A B C Label
0 2 2 2 1
1 3 3 3 2
2 4 4 4 3
3 3 3 3 2
scipy.spatial.distance.cdist
+ np.where
ary=scipy.spatial.distance.cdist(df1[['A', 'B', 'C']], df2[['A', 'B', 'C']], metric='euclidean')
order=np.where(ary==ary.min(1)[:,None])
df2['New']=df1.reindex(order[1]).Label.values
df2
Out[612]:
A B C Label New
0 3 3 3 2 2
1 2 2 2 1 1
2 4 4 4 3 3
编辑:通过使用 cold 的 argmin()
ary = scipy.spatial.distance.cdist(df2[['A', 'B', 'C']], df1[['A', 'B', 'C']], metric='euclidean')
df2['New']=df1.reindex(ary.argmin(1)).Label.values
df2
Out[659]:
A B C Label New
0 3 3 3 2 2
1 2 2 2 1 1
2 4 4 4 3 3
3 3 3 3 3 2