You need to enable JavaScript to run this app. Pandas 读取CSV时移除每行前导NaN,左移行且保留非前导位置NaN
优惠活动
大模型
产品
解决方案
定价
更多

Pandas 读取CSV时移除每行前导NaN,左移行且保留非前导位置NaN

你之前尝试的代码存在本质逻辑偏差:df.first_valid_index()是针对整个DataFrame查找第一个非空行的索引位置做行切片,属于行维度的操作,完全没有涉及逐行扫描、移除每行左侧连续前导NaN、将剩余内容左移对齐的列维度处理,自然达不到预期效果。

需求实现方案

核心逻辑:逐行定位每行第一个非NaN值的位置,将该位置及后续所有元素整体左移对齐到行的最左侧,行末尾空出的位置自动补NaN,全程保留元素原有的相对位置,不会删除非前导位置的任何NaN值。

中小规模数据集:逐行apply实现(代码简洁易读)

定义逐行处理的函数,再批量应用到DataFrame上:

import pandas as pd
import numpy as np

def left_align_row(row):
    # 定位当前行第一个非NaN值的列名
    first_valid_col = row.first_valid_index()
    # 整行都是NaN的场景直接返回
    if first_valid_col is None:
        return row
    # 计算左移的偏移量:即当前行开头连续NaN的个数
    offset = row.index.get_loc(first_valid_col)
    # 整体左移offset位,末尾自动补NaN
    return row.shift(-offset)

# 逐行应用处理
df_processed = df.apply(left_align_row, axis=1)

用你提供的示例数据集测试,输出结果和你预期的对齐效果完全一致:

c1c2c3c4c5c6
020.0NaN250.0250.0NaNNaN
130.074.0290.0NaNNaNNaN
265.0340.0340.0340.0NaNNaN
3325.0325.0NaN325.0NaNNaN
4345.0345.0345.0345.0NaNNaN
517.074.0315.0315.0NaNNaN
682.0248.0248.0248.0NaNNaN

大规模数据集:向量化实现(处理效率更高)

如果读取的CSV行数很多(十万级以上),逐行apply的Python循环效率较低,可以用NumPy的向量化操作批量计算每行的左移偏移量,整体处理速度能提升一个数量级:

# 生成非NaN的布尔掩码
is_not_nan = df.notna().to_numpy()
# 逐行计算前导NaN的个数(即需要左移的偏移量)
leading_nan_counts = (~is_not_nan).cumprod(axis=1).sum(axis=1)
# 逐行执行左移操作
raw_values = df.to_numpy()
processed_values = np.array([
    np.roll(row, -cnt) if cnt > 0 else row
    for row, cnt in zip(raw_values, leading_nan_counts)
])
# 还原为带原列名的DataFrame
df_processed = pd.DataFrame(processed_values, columns=df.columns)

对接原有CSV读取流程

不需要修改原有的读取代码,把处理逻辑直接接入即可:

response = pd.read_csv(r'MonthlyPermitReport.csv')
df_processed = response.apply(left_align_row, axis=1)

内容的提问来源于stack exchange,提问作者Phil_in_Tx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.31 03:54:06