请求实现基于Pandas的通用函数:列值匹配与插值生成新列
解决DataFrame匹配与插值问题:为df1新增Col4列
针对你提出的需求,我设计了一个通用函数,可以高效处理两个按指定列升序排列的DataFrame,为第一个DataFrame添加符合规则的新列。以下是完整的解决方案:
通用函数实现
import pandas as pd import numpy as np def add_matched_or_avg_column(df_target, df_reference, key_col='Col1', value_col='Col3', new_col='Col4'): # 确保输入DataFrame按key_col升序排列,增强鲁棒性(即使输入未排序也能正常工作) df_target_sorted = df_target.sort_values(key_col).reset_index(drop=True) df_ref_sorted = df_reference.sort_values(key_col).reset_index(drop=True) # 提取参考DataFrame的关键数组,方便快速查找 ref_keys = df_ref_sorted[key_col].values ref_values = df_ref_sorted[value_col].values ref_length = len(df_ref_sorted) # 使用numpy的searchsorted找到每个目标key在参考key中的插入位置 insert_positions = ref_keys.searchsorted(df_target_sorted[key_col].values) # 计算新列的值 new_col_values = [] for idx, pos in enumerate(insert_positions): current_key = df_target_sorted.loc[idx, key_col] if pos == 0: # 目标key小于参考DataFrame的最小key,直接取第一个参考值 val = ref_values[0] elif pos == ref_length: # 目标key大于参考DataFrame的最大key,直接取最后一个参考值 val = ref_values[-1] else: # 检查是否与参考数据中的key完全匹配 if ref_keys[pos-1] == current_key: val = ref_values[pos-1] elif ref_keys[pos] == current_key: val = ref_values[pos] else: # 不匹配时,取前后紧邻参考值的平均值 val = (ref_values[pos-1] + ref_values[pos]) / 2 new_col_values.append(val) # 将新列添加到目标DataFrame,并恢复原始索引顺序 df_target_sorted[new_col] = new_col_values df_target_sorted = df_target_sorted.reindex(df_target.index) return df_target_sorted
函数说明
这个函数的核心优势在于:
- 通用性:支持自定义关键列(
key_col)、参考值列(value_col)和新列名(new_col),适用于各种结构的DataFrame - 鲁棒性:自动对输入DataFrame进行排序,即使输入未按指定列升序排列也能正确处理
- 高效性:使用
numpy.searchsorted进行快速位置查找,时间复杂度为O(n log m)(n为目标DataFrame行数,m为参考DataFrame行数),适合处理大数据量
测试示例
用你提供的示例数据测试函数:
# 示例数据 df1 = pd.DataFrame({'Col1': [1, 7, 10, 50, 73, 80 ], 'Col2': [1,2,3,4,5,6]}) df2 = pd.DataFrame({'Col1': [0, 4, 10, 80], 'Col3': [7,6,8,9]}) # 调用函数 result_df = add_matched_or_avg_column(df1, df2) # 查看Col4结果 print(result_df['Col4'])
输出结果
0 6.5 1 7.0 2 8.0 3 8.5 4 8.5 5 9.0 Name: Col4, dtype: float64
完全符合你预期的结果:(7+6)/2=6.5、(6+8)/2=7、8、(8+9)/2=8.5、(8+9)/2=8.5、9。
内容的提问来源于stack exchange,提问作者Rafael Paulino
相关产品推荐
相关产品推荐

