Pandas DataFrame列转Float异常:字符串形式人脸嵌入向量处理问题
问题解决步骤
1. 向量实际存储格式的排查方法
- 不要依赖Excel判断存储格式:Excel是纯文本渲染逻辑,只要单元格内的字符串内容和真实数组的显示字符一致,就会呈现完全一样的视觉效果,肉眼无法分辨底层数据是字符串还是真正的数值数组。
- 正确排查方式直接在Python运行环境下执行如下代码:
正常存储完整数值向量的列类型应为数值型,你当前场景下的输出结果必然是# 查看向量列的整体存储类型 print(meta_data_imdb['vecteur'].dtype) # 查看单个单元格的真实Python数据类型 print(type(meta_data_imdb['vecteur'].iloc[0]))object类型的列、str类型的单值,即可确认向量被存储为了字符串。
2. 字符串形式向量的转换方法
ast模块转换失败的原因
ast.literal_eval仅能解析严格符合Python语法规则的字面量字符串,要求列表元素之间必须用逗号分隔。但你存储的向量字符串是空格分隔的数值(形如"[ 3.85 0.45 ... ]"),完全不符合解析规则,自然会抛出语法错误。
正确的转换实现
针对空格分隔、带方括号的字符串格式,用numpy原生的解析方法效率远高于ast,且完全兼容该格式:
import numpy as np def str2vector(s): # 去除字符串首尾的方括号 clean_str = s.strip('[]') # 按任意空白分隔符拆分解析为浮点数组 return np.fromstring(clean_str, sep=' ') # 批量转换DataFrame内的所有向量 meta_data_imdb['vecteur'] = meta_data_imdb['vecteur'].apply(str2vector)
必须排查的隐藏问题
如果你的字符串内本身带有...省略号占位,说明当初存CSV的时候,误把numpy数组打印输出时的截断内容存进去了——这种情况的向量本身是不完整的,就算转换成功也会因为缺失中间维度的数值,导致余弦距离计算完全失效,必须回到最初存库的环节重新导出完整的向量值。
跑通距离计算的注意事项
转换完成后,向量列存储的就是真正的numpy浮点数组,只需在距离计算函数内增加类型强制转换的逻辑,即可彻底消除类型兼容问题:
def calculerDistance(vec_lib, vec_user): # 强制转换为64位浮点数数组,消除格式差异 vec_lib = np.asarray(vec_lib, dtype=np.float64) vec_user = np.asarray(vec_user, dtype=np.float64) # 计算余弦距离(1减去余弦相似度) cos_sim = np.dot(vec_lib, vec_user) / (np.linalg.norm(vec_lib) * np.linalg.norm(vec_user)) return 1 - cos_sim
对应调整后的完整运行逻辑如下:
vect = calculVecteur('imagesUtilisateur/test.jpg', model) meta_data_imdb = pd.read_csv("resources/vectorisation/imdb_metadata_v.csv") # 先批量转换字符串向量为真实数值数组 meta_data_imdb['vecteur'] = meta_data_imdb['vecteur'].apply(str2vector) # 再逐行计算距离 meta_data_imdb['distance'] = meta_data_imdb['vecteur'].apply(lambda x: calculerDistance(x, vect))
内容的提问来源于stack exchange,提问作者user13948043
相关产品推荐
相关产品推荐

