You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用另一列上一行值填充Pandas DataFrame的NaN?自定义函数报错排查

Pandas填充NaN值函数的问题分析

问题背景

现有如下Pandas DataFrame:

import pandas as pd
import numpy as np

df = pd.DataFrame({"A":[0,np.nan,0,0,np.nan,1,np.nan,1,0,np.nan],
                   "B":[0,1,0,0,1,1,1,0,0,0]})

需求:将A列中的NaN值替换为B列上一行对应的值,比如第2行(索引1)A列的NaN要替换为第1行(索引0)B列的0,第7行(索引6)A列的NaN要替换为第6行(索引5)B列的1。

用户定义了如下函数,但用apply调用后无法正常工作:

def impute_with_previous_B(df):
    for x in range(len(df)):
        if pd.isnull(df.loc[x,"A"]) == True:
            df.loc[x,"A"] = df.loc[x-1,"B"]

df["A"] = df.apply(lambda x: impute_with_previous_B(x),axis=1)

错误原因分析

  1. apply(axis=1)参数理解错误:apply(axis=1)是逐行处理数据,传入函数的是单行的Series对象,而非整个DataFrame。你的函数里依然用df.loc[x,"A"]这种操作整个DataFrame的写法,完全不匹配传入的参数,自然无法执行。
  2. 函数无返回值:你的函数没有任何return语句,apply执行后会返回一堆None,赋值给df["A"]会直接把整列变成NaN。
  3. 循环逻辑的潜在问题:就算不用apply,直接调用这个函数,当索引为0(第一行)时,x-1=-1会取到DataFrame最后一行的B值,这不符合常规需求(第一行的NaN通常需要保留或单独处理)。

正确实现方式

推荐:Pandas向量化操作(高效简洁)

不用循环,直接通过布尔索引结合shift()方法实现,这是Pandas的最优写法:

# 筛选A列为NaN的行,将其值替换为B列上一行的值
df.loc[df["A"].isna(), "A"] = df["B"].shift(1)

执行后结果符合需求:

AB
0.00
0.01
0.00
0.00
0.01
1.01
1.01
1.00
0.00
0.00

可选:循环实现(仅作理解用,不推荐)

如果一定要用循环,直接遍历DataFrame的索引即可,不需要apply:

for idx in df.index:
    if pd.isna(df.loc[idx, "A"]):
        # 跳过第一行,避免取到最后一行的B值
        if idx > 0:
            df.loc[idx, "A"] = df.loc[idx-1, "B"]
        # 可选:如果第一行A是NaN,可以在这里加else处理,比如保持NaN

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 06:03:18