Pandas:按索引范围为大行数DataFrame匹配日期并拼接内容
高效匹配DataFrame并拼接日期的方法
针对20万行级别的DataFrame,要避免循环迭代,用pandas的矢量化操作可以大幅提升效率,推荐使用merge_asof方法实现需求,具体步骤如下:
1. 预处理DF B
DF B的索引是DF A中的分界位置,首先需要重置索引并排序,确保匹配时的有序性:
import pandas as pd # 重置DF B的索引,将原索引转为DF A的索引列,并重命名 df_b_processed = df_b.reset_index().rename(columns={'index': 'a_index'}) # 按DF A的索引列排序,merge_asof要求右表必须有序 df_b_processed = df_b_processed.sort_values('a_index').reset_index(drop=True)
2. 处理边界情况(可选)
如果DF B的最小a_index大于0,需要补充起始行,确保DF A的前几行能匹配到日期:
# 获取DF B的第一个日期,添加a_index=0的行 first_date = df_b_processed['Dates'].iloc[0] df_b_processed = pd.concat( [pd.DataFrame({'a_index': [0], 'Dates': [first_date]}), df_b_processed], ignore_index=True )
3. 给DF A添加索引列
为了和DF B匹配,给DF A添加一列对应自身索引:
df_a['a_index'] = df_a.index
4. 用merge_asof匹配日期
merge_asof会按a_index为DF A的每一行找到最近的、索引不超过当前行的DF B记录,匹配对应的日期,这一步是矢量化操作,速度远快于循环:
# direction='backward'表示找小于等于当前键的最大匹配项 df_merged = pd.merge_asof(df_a, df_b_processed, on='a_index', direction='backward')
5. 拼接日期和条目
将日期和原条目拼接,得到最终结果:
# 拼接日期与Entries列 df_merged['Entries'] = df_merged['Dates'] + ' ' + df_merged['Entries'] # 清理不需要的列,得到最终DF df_result = df_merged.drop(columns=['a_index', 'Dates'])
替代方案:使用pd.cut(适合区间明确的场景)
如果DF B的日期对应连续的索引区间,也可以用pd.cut实现:
# 提取分界点并补充首尾 cut_points = [0] + df_b_processed['a_index'].tolist() + [df_a.index.max()] # 对应日期列表,补充首尾以匹配区间数量 dates = [df_b_processed['Dates'].iloc[0]] + df_b_processed['Dates'].tolist() + [df_b_processed['Dates'].iloc[-1]] # 将DF A的索引映射到对应日期 df_a['Dates'] = pd.cut(df_a.index, bins=cut_points, labels=dates, include_lowest=True) # 拼接日期与条目 df_a['Entries'] = df_a['Dates'] + ' ' + df_a['Entries']
两种方法都能高效处理20万行数据,其中merge_asof更灵活,适合DF B中存在重复日期或非连续分界点的场景。
内容的提问来源于stack exchange,提问作者Unsullied
相关产品推荐
相关产品推荐

