Pandas使用bfill填充日期缺失值时全空列消失如何解决?
全空列执行bfill后消失的核心原因
- 动态列索引的引用联动问题:你写的
cols = new.columns获取的不是独立的列名拷贝,是和DataFrame底层列结构绑定的引用。当链式操作new[cols].apply(pd.to_datetime).bfill(axis=1)的返回结果缺失列时,后续的原地赋值new[cols] = 计算结果会自动更新new的列结构,把结果中没有匹配到的列直接移除,连带绑定的cols索引同步变更,最终打印时就看不到原本存在的全空列。 - 全空列的隐式剔除机制:在1.4.x ~ 2.0.x版本的pandas中,执行
bfill(axis=1)(按行反向填充)时,如果某列全为NaN、所有非空值完全来自右侧相邻列的填充,pandas会把这列判定为无独立值的冗余列,在返回结果时直接从索引中剔除,不会保留空列的位置。这就是你那个全空列消失的直接触发点。
可落地的修正方案
- 全程使用硬编码的目标列列表作为锚点,不要依赖动态从DataFrame中获取的列名,从根源上避免引用联动带来的结构变动。
- 拆分链式操作,在每一步转换、填充操作后,显式用
reindex对齐列顺序,强制保留所有目标列的位置——哪怕中间步骤丢了列,reindex也会自动把缺失的列补成全NaT的空列,保证列结构不丢。 - 给
pd.to_datetime显式设置errors='coerce'参数,避免因为非日期值的解析异常,导致全空列被静默丢弃。
修正后的核心代码:
# 固定锚点:所有操作全程要保留的目标列 TARGET_COLS = [ 'Actual Start', 'FOR CLIENT SUBMISSION / APPROVAL-Issued for Self Discipline Check (SDC)(Actual Finish Date)', 'FOR CLIENT SUBMISSION / APPROVAL-Issued for Inter-disciplinary Check (IDC)(Actual Finish Date)', 'FOR CLIENT SUBMISSION / APPROVAL-Submission to client(Actual Finish Date)', 'FOR CLIENT SUBMISSION / APPROVAL-Reviewed by Client(Actual Finish Date)', 'FOR CLIENT SUBMISSION / APPROVAL-Approved by Client (FAC)(Actual Finish Date)', 'FOR CLIENT SUBMISSION / APPROVAL-Issue for Construction(Actual Finish Date)', 'FOR PR with offer Evaluation-Discipline Completed (SDC)(Actual Finish Date)', 'FOR PR with offer Evaluation-Issuance to procurement team (FRB)(Actual Finish Date)', 'FOR PR with offer Evaluation-Tech. Evaluation Completion(Actual Finish Date)' ] for f in glob.glob("Raw/*.xlsx"): xls = pd.ExcelFile(f) df1 = xls.parse(sheet_name=0) # 直接用固定列名提取子集,避免filter逻辑漏列 new = df1[TARGET_COLS].copy() # 日期转换,显式设置异常值为NaT new = new.apply(pd.to_datetime, errors='coerce') # 对齐列顺序,补回可能丢失的列 new = new.reindex(columns=TARGET_COLS) # 按行反向填充,操作完成后再次对齐列结构 new = new.bfill(axis=1).reindex(columns=TARGET_COLS) # 此时打印的列列表和目标列完全一致 print(new.columns.tolist())
补充说明:日常写代码时,尽量避免对全空列做链式的原地赋值操作,所有涉及列结构变动的步骤都要以固定列名列表为基准做对齐,就能从根源上避免这类隐式丢列的问题。
内容的提问来源于stack exchange,提问作者Debayan
相关产品推荐
相关产品推荐

