Python DataFrame中3天内双向交互且数值差10%以内记录查询实现
实现代码
import pandas as pd # 构建数据集 data3 = [[20210308, 'A','B',100], [20210307, 'B','A',95], [20210307, 'B','A',65], [20210305, 'A','C',50], [20210304, 'D','E',25], [20210303, 'E','D',200], [20210201,'E','B',10 ], [20210101, 'X','X',50]] df3 = pd.DataFrame(data3, columns = ['Date_1', 'Interactor_A','Interactor_B','Value']) df3['Date_2'] = pd.to_datetime(df3['Date_1'], format='%Y%m%d') # 自连接匹配双向交互对 df_merge = df3.reset_index().merge( df3.reset_index(), left_on=['Interactor_A', 'Interactor_B'], right_on=['Interactor_B', 'Interactor_A'], suffixes=('_left', '_right') ) # 多条件过滤 filter_mask = ( # 避免同一对记录重复匹配,同时排除自身和自身匹配的无效结果 (df_merge['index_left'] < df_merge['index_right']) & # 显式过滤自身交互记录 (df_merge['Interactor_A_left'] != df_merge['Interactor_B_left']) & # 时间差不超过3天 (abs(df_merge['Date_2_left'] - df_merge['Date_2_right']).dt.days <= 3) & # 数值比值在90%~110%区间 (df_merge[['Value_left', 'Value_right']].min(axis=1) / df_merge[['Value_left', 'Value_right']].max(axis=1) >= 0.9) ) # 提取符合条件的所有索引,去重后取数 valid_indexes = pd.concat([df_merge.loc[filter_mask, 'index_left'], df_merge.loc[filter_mask, 'index_right']]).unique() result = df3.loc[valid_indexes] print(result)
运行结果
Date_1 Interactor_A Interactor_B Value Date_2 0 20210308 A B 100 2021-03-08 1 20210307 B A 95 2021-03-07
关键逻辑说明
- 自连接时通过交叉匹配交互人字段,直接筛选出双向交互的配对组合
index_left < index_right条件既避免了同一对记录重复匹配,也排除了单条记录和自身匹配的无效结果- 数值比较采用最小值除以最大值的写法,不用分别判断两种除法场景,逻辑更简洁
- 最终合并匹配到的左右索引去重,即可从原表提取所有符合要求的记录
内容的提问来源于stack exchange,提问作者Malik
相关产品推荐
相关产品推荐

