如何在Python中按薪资值的接近程度升序映射两个DataFrame?
需求实现:按薪资接近度匹配排序
现有DataFrame定义
import pandas as pd # 创建df_1 data_set_1 = { 'id': [1, 2, 3, 4, 5], 'Available_Salary': [10, 20, 30, 40, 50] } df_1 = pd.DataFrame(data_set_1) print("\n df_1 = \n", df_1) # 创建df_2 data_set_2 = { 'id': [1, 2, 3, 4], 'Expected_Salary': [16, 42, 28, 32] } df_2 = pd.DataFrame(data_set_2) print("\n df_2 = \n", df_2)
需求说明
对df_2中的每一条记录(按id区分),计算其Expected_Salary与df_1中所有Available_Salary的差值绝对值,按差值从小到大排序,得到对应的df_1的id和Available_Salary,最终生成包含df_2信息、排序后匹配项的结果DataFrame。
实现代码
import pandas as pd # 定义原始数据 data_set_1 = {'id': [1,2,3,4,5], 'Available_Salary': [10,20,30,40,50]} df_1 = pd.DataFrame(data_set_1) data_set_2 = {'id': [1,2,3,4], 'Expected_Salary': [16,42,28,32]} df_2 = pd.DataFrame(data_set_2) # 生成全量组合并计算差值绝对值 cross_combined = df_2.assign(temp_key=1).merge(df_1.assign(temp_key=1), on='temp_key').drop('temp_key', axis=1) cross_combined['abs_diff'] = abs(cross_combined['Expected_Salary'] - cross_combined['Available_Salary']) # 按df_2的id分组,对差值进行升序排名 cross_combined['match_rank'] = cross_combined.groupby('id_x')['abs_diff'].rank(method='first', ascending=True).astype(int) # 转换为目标宽表格式 result_df = cross_combined.pivot( index=['id_x', 'Expected_Salary'], columns='match_rank', values=['id_y', 'Available_Salary'] ).reset_index() # 重命名列名,提升可读性 result_df.columns = [ 'df2_id', 'expected_salary', 'match_id_1', 'match_id_2', 'match_id_3', 'match_id_4', 'match_id_5', 'match_salary_1', 'match_salary_2', 'match_salary_3', 'match_salary_4', 'match_salary_5' ] print("\n 结果DataFrame = \n", result_df)
代码解释
- 全量组合生成:通过临时关联键将两个DataFrame做笛卡尔积,得到所有期望薪资与可用薪资的组合。
- 差值计算:计算每组组合的薪资差值绝对值,作为接近程度的衡量标准。
- 分组排名:按df_2的
id分组,对每组内的差值进行升序排名,确保相同差值时保留原始顺序。 - 格式转换:用透视表将长表转换为宽表,每一行对应df_2的一条记录,列对应不同排名的匹配结果。
- 列名优化:将自动生成的多级列名改为直观命名,方便查看。
运行结果
输出的结果DataFrame如下:
df2_id expected_salary match_id_1 match_id_2 match_id_3 match_id_4 match_id_5 match_salary_1 match_salary_2 match_salary_3 match_salary_4 match_salary_5 0 1 16 2 1 3 4 5 20 10 30 40 50 1 2 42 4 5 3 2 1 40 50 30 20 10 2 3 28 3 2 4 1 5 30 20 40 10 50 3 4 32 3 4 2 5 1 30 40 20 50 10
内容的提问来源于stack exchange,提问作者NN_Developer
相关产品推荐
相关产品推荐

