Python中对DataFrame行迭代执行向量间计算的实现方法
实现DataFrame中向量两两计算的方法
嘿,我来帮你搞定这个向量两两计算的需求~ 假设你用的是pandas和numpy(这俩是处理这类数据的标配),我给你分两种场景来写实现方法,你按需选就行:
场景1:所有向量两两组合(不区分字母分组)
如果需要对整个DataFrame里的所有向量进行无序两两配对(比如向量0和1算一组,不会重复算1和0),可以这么做:
步骤1:先构造示例数据(和你给的一致)
import pandas as pd import numpy as np from itertools import combinations # 构造你的示例DataFrame data = { 'letter': ['a', 'a', 'a', 'i', 'u', 'u', 'i'], 'vector': [ [2.5, 4.7, 235, 46, 34], [2.5, 5, 234, 345.8, 1], [2.5, 5, 234, 432.6, 1], [4.7, 34.2, 3, 34, 700], [4.7, 123, 123, 13, 66], [4.7, 13, 375, 123, 66], [4.7, 15, 375, 23, 656] ] } df = pd.DataFrame(data)
步骤2:定义你的计算函数
这里我以欧氏距离为例,你可以把函数里的逻辑换成你需要的计算(比如余弦相似度、点积等等):
def calculate_pair(vec1, vec2): # 把列表转成numpy数组,方便计算 vec1_np = np.array(vec1) vec2_np = np.array(vec2) # 这里替换成你实际需要的计算逻辑 return np.linalg.norm(vec1_np - vec2_np)
步骤3:生成所有两两组合并计算
# 生成所有索引的两两组合(无序) pairs = list(combinations(df.index, 2)) # 遍历每个组合,执行计算并收集结果 results = [] for idx1, idx2 in pairs: vec1 = df.loc[idx1, 'vector'] vec2 = df.loc[idx2, 'vector'] letter1 = df.loc[idx1, 'letter'] letter2 = df.loc[idx2, 'letter'] calc_result = calculate_pair(vec1, vec2) results.append({ 'idx1': idx1, 'letter1': letter1, 'idx2': idx2, 'letter2': letter2, 'calculation_result': calc_result }) # 把结果转成DataFrame,方便查看 result_df = pd.DataFrame(results) print(result_df.head())
如果需要有序的两两配对(比如同时计算(0,1)和(1,0)),只需要把combinations换成itertools.product,并加上repeat=2,同时过滤掉自己和自己配对的情况(如果不需要的话):
from itertools import product pairs = list(product(df.index, df.index)) # 过滤掉idx1 == idx2的情况 pairs = [pair for pair in pairs if pair[0] != pair[1]]
场景2:按字母分组后,组内向量两两计算
如果你的需求是同一字母下的向量两两计算,那可以先按letter分组,再对每组执行上面的逻辑:
group_results = [] # 按letter分组遍历 for letter, group in df.groupby('letter'): # 生成组内索引的两两组合 group_pairs = list(combinations(group.index, 2)) for idx1, idx2 in group_pairs: vec1 = group.loc[idx1, 'vector'] vec2 = group.loc[idx2, 'vector'] calc_result = calculate_pair(vec1, vec2) group_results.append({ 'letter': letter, 'idx1': idx1, 'idx2': idx2, 'calculation_result': calc_result }) group_result_df = pd.DataFrame(group_results) print(group_result_df.head())
优化:大数据集的高效计算
如果你的数据集很大(向量维度高、行数多),循环遍历会很慢,建议把vector列转成numpy矩阵,用向量化操作来批量计算:
# 把vector列转成numpy矩阵 vec_matrix = np.array(df['vector'].tolist()) # 计算所有两两欧氏距离(用广播实现,效率极高) # 结果是一个对称矩阵,dist_matrix[i][j]就是第i个向量和第j个向量的距离 dist_matrix = np.sqrt(((vec_matrix[:, np.newaxis] - vec_matrix)**2).sum(axis=2)) # 把矩阵转成DataFrame格式(可选) dist_df = pd.DataFrame(dist_matrix, index=df.index, columns=df.index)
这样比循环快几十甚至上百倍,非常适合大数据场景~
内容的提问来源于stack exchange,提问作者MeC
相关产品推荐
相关产品推荐

