Pandas多层索引DataFrame通过移位新增前K日新闻列的实现问题
实现历史新闻分组笛卡尔积拼接的Pandas方案
预处理步骤
首先先对原始DataFrame做基础格式调整,确保日期列是datetime类型,且按日期、分组设置多级索引提升查询效率:
import pandas as pd from datetime import timedelta # 转换日期格式 df['Date'] = pd.to_datetime(df['Date']) # 设置多级索引并排序 df = df.set_index(['Date', 'Group']).sort_index() # 自定义需要取的历史天数K K = 2
核心实现逻辑
逐行处理原始数据中的每条记录,取出对应前K天的所有分组新闻,做笛卡尔积后和当前记录拼接:
def merge_historical_titles(row): target_date = row.name[0] history_list = [] # 依次取前1天到前K天的历史数据 for day_offset in range(1, K+1): hist_date = target_date - timedelta(days=day_offset) # 判断历史日期是否存在数据 if hist_date in df.index.get_level_values('Date'): # 取出该日期所有分组的Titles数据 hist_titles = df.xs(hist_date, level='Date')['Titles'].tolist() else: # 无历史数据时填充空列表,可按需调整为跳过该行逻辑 hist_titles = [[]] history_list.append(pd.DataFrame({f'Titles-{day_offset}': hist_titles})) # 所有历史日期的分组做笛卡尔积 cross_result = history_list[0] for hist_df in history_list[1:]: cross_result = cross_result.merge(hist_df, how='cross') # 补充当前行的基础信息 cross_result['Date'] = target_date cross_result['Group'] = row.name[1] cross_result['Titles'] = row['Titles'] cross_result['Label'] = row['Label'] return cross_result # 拼接所有处理后的结果 final_df = pd.concat( [merge_historical_titles(row) for _, row in df.iterrows()], ignore_index=True ) # 调整列顺序符合需求 final_df = final_df[ ['Date', 'Group', 'Titles'] + [f'Titles-{i}' for i in range(1, K+1)] + ['Label'] ]
优化提示
- 若存在无历史数据的日期,可根据业务需求修改
hist_titles = [[]]的逻辑,改为跳过该行避免无效样本; - 若K值较大导致笛卡尔积后样本量过高,可拆分final_df为多个子块分批输入训练,进一步降低内存占用。
内容的提问来源于stack exchange,提问作者Nicolò Antonucci
相关产品推荐
相关产品推荐

