如何基于三个给定值从pandas DataFrame匹配最接近的情绪类别
三维浮点输入匹配最近情绪类别的实现
实现原理
匹配最近情绪的核心是计算输入的三个浮点值组成的向量,和DataFrame中每一行情绪对应的三维特征向量的距离,返回距离最小的类别即可。需要注意最初代码的逻辑问题:直接遍历DataFrame调用min是不对的,pandas的DataFrame直接迭代会按列返回列对象,根本不会逐行计算匹配值,无法得到正确结果。
向量化实现(运算效率最高)
不用逐行循环,直接用pandas内置的向量化运算算距离,速度快,也不会临时修改原DataFrame的结构:
import pandas as pd import numpy as np def closest_values(df, input_n1, input_n2, input_n3): # 计算每行特征和输入值的欧氏距离平方,省掉开根号步骤不影响排序结果,减少计算量 distance = ( (df['n1'] - input_n1)**2 + (df['n2'] - input_n2)**2 + (df['n3'] - input_n3)**2 ) # 找到距离最小的行索引,返回对应的情绪类别 closest_row_idx = distance.idxmin() return df.loc[closest_row_idx, 'Category']
测试给出的示例输入:
df_emotional = pd.DataFrame({ 'Category' : ['anger', 'disgust', 'fear', 'guilt', 'joy', 'negative', 'positive', 'sadness', 'shame'], 'n1' : [0.167, 0.052, 0.073, 0.208, 0.980, 0.102, 0.959, 0.052, 0.060], 'n2' : [0.865, 0.775, 0.840, 0.567, 0.824, 0.527, 0.510, 0.288, 0.670], 'n3' : [0.657, 0.317, 0.293, 0.206, 0.794, 0.176, 0.855, 0.164, 0.155] }) # 调用后返回结果为anger,和预期输出完全一致 closest_values(df_emotional, 0.161, 0.991, 0.632)
纯Pandas实现版本
如果不想引入numpy依赖,用曼哈顿距离(绝对偏差和)计算也能达到同样效果:
def closest_values(df, input_n1, input_n2, input_n3): # 逐行计算三个特征和输入值的绝对偏差总和 temp_dist = ( (df['n1'] - input_n1).abs() + (df['n2'] - input_n2).abs() + (df['n3'] - input_n3).abs() ) # 取偏差最小的行对应的类别 closest_idx = temp_dist.idxmin() return df.loc[closest_idx, 'Category']
常见注意点
- 要是需要给三个特征设置不同的计算权重,直接在距离项里乘对应权重系数就行。比如需要给n2分配2倍权重,把对应计算项改成
(2*(df['n2'] - input_n2))**2即可 - 如果三个特征的数值范围差得特别大(比如一个是0-1的比例值,另一个是0-100的计数值),得先把所有特征归一化到同一数值范围再算距离,不然数值大的特征会完全主导匹配结果,结果会失真
内容的提问来源于stack exchange,提问作者Y4RD13
相关产品推荐
相关产品推荐

