基于Pandas逐行比对两个DataFrame并执行距离计算的需求
Pandas双DataFrame按双列匹配计算坐标距离并生成新列
需求概述
已有两个Pandas DataFrame(DF1、DF2),需完成以下操作:
- 仅匹配PARTICIPANT和TRIAL值均相同的DF1与DF2行
- 用
math.dist计算DF1中PRE_FIX_X/Y与DF2中POST_FIX_X/Y的欧氏距离 - 若距离≤150,将对应DF2行的
CURRENT_FIX_INDEX记录到DF1新增的REFIX列(多个值用逗号分隔) - 最终将处理后的DF1保存为CSV文件
示例数据
DF1(原始数据)
| IP_INDEX | IP_LABEL | PARTICIPANT | TRIAL | CURRENT_FIX_INDEX | PRE_FIX_X | PRE_FIX_Y |
|---|---|---|---|---|---|---|
| 1 | 前3秒 | a | 1 | 1 | 550 | 150 |
| 1 | 前3秒 | a | 1 | 2 | 600 | 300 |
| 1 | 前3秒 | a | 2 | 1 | 250 | 600 |
| 1 | 前3秒 | b | 1 | 1 | 400 | 400 |
| 1 | 前3秒 | b | 2 | 1 | 600 | 400 |
DF2(匹配数据源)
| IP_INDEX | IP_LABEL | PARTICIPANT | TRIAL | CURRENT_FIX_INDEX | POST_FIX_X | POST_FIX_Y |
|---|---|---|---|---|---|---|
| 2 | 后3秒 | a | 1 | 1 | 500 | 200 |
| 2 | 后3秒 | a | 1 | 2 | 650 | 350 |
| 2 | 后3秒 | a | 2 | 1 | 300 | 650 |
| 2 | 后3秒 | b | 1 | 1 | 250 | 700 |
| 2 | 后3秒 | b | 1 | 2 | 450 | 150 |
| 2 | 后3秒 | b | 2 | 1 | 550 | 350 |
| 2 | 后3秒 | b | 2 | 2 | 350 | 550 |
实现逻辑
- 给DF1新增空列
REFIX - 按
PARTICIPANT和TRIAL对DF2分组,仅处理与DF1匹配的分组 - 对每个匹配分组内的DF1行,计算其与DF2所有行的坐标距离
- 筛选距离≤150的DF2行,收集对应的
CURRENT_FIX_INDEX并以逗号连接,赋值给DF1的REFIX列 - 导出处理后的DF1为CSV文件
代码实现
import pandas as pd import math # 初始化REFIX列为空字符串 df1['REFIX'] = '' # 按PARTICIPANT和TRIAL分组处理DF2,减少无效匹配 for (participant, trial), df2_group in df2.groupby(['PARTICIPANT', 'TRIAL']): # 定位DF1中当前分组的行 df1_mask = (df1['PARTICIPANT'] == participant) & (df1['TRIAL'] == trial) df1_matched_rows = df1[df1_mask] if df1_matched_rows.empty: continue # 遍历DF1当前分组的每一行 for idx, row1 in df1_matched_rows.iterrows(): # 计算当前DF1行与DF2分组内所有行的欧氏距离 distances = df2_group.apply( lambda row2: math.dist( [row1['PRE_FIX_X'], row1['PRE_FIX_Y']], [row2['POST_FIX_X'], row2['POST_FIX_Y']] ), axis=1 ) # 筛选符合距离条件的CURRENT_FIX_INDEX,转为字符串后用逗号连接 valid_indices = df2_group[distances <= 150]['CURRENT_FIX_INDEX'].astype(str) df1.loc[idx, 'REFIX'] = ','.join(valid_indices) # 保存处理后的DF1到CSV df1.to_csv('processed_df1.csv', index=False)
代码说明
- 采用
groupby分组处理,避免全量笛卡尔积匹配,提升10000+行数据的处理效率 - 用
math.dist直接计算二维坐标的欧氏距离,逻辑清晰 - 对符合条件的索引进行字符串转换后拼接,保证
REFIX列格式符合要求
处理后DF1示例
| IP_INDEX | IP_LABEL | PARTICIPANT | TRIAL | CURRENT_FIX_INDEX | PRE_FIX_X | PRE_FIX_Y | REFIX |
|---|---|---|---|---|---|---|---|
| 1 | 前3秒 | a | 1 | 1 | 550 | 150 | 1 |
| 1 | 前3秒 | a | 1 | 2 | 600 | 300 | 1,2 |
| 1 | 前3秒 | a | 2 | 1 | 250 | 600 | 1 |
| 1 | 前3秒 | b | 1 | 1 | 400 | 400 | |
| 1 | 前3秒 | b | 2 | 1 | 600 | 400 | 1 |
内容的提问来源于stack exchange,提问作者Eslifkin
相关产品推荐
相关产品推荐

