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

求助:Pandas中for循环内.replace无法按行迭代替换NaN值

问题

需要将DataFrame中Leg和SAP列的NaN值替换为对应行的ID列值,且不修改其他列。但使用for循环调用pandas.replace()时,所有NaN都被替换成了同一个ID值,无法按行对应替换。

代码示例

import pandas as pd
import numpy as np

df1 = pd.read_csv("df1.csv")
df2 = pd.read_csv("df2.csv")

print(df1)
print(df2)

df3 = pd.merge(df1, df2, on='ID', how='left')

print(df3)

C = len(df3.index)

for i in range(C):
    if pd.isnull(df3.at[i, 'Leg']) == True:
        df3.replace((df3.at[i, 'Leg']), (df3.at[i, 'ID']), inplace=True)
        df3.replace((df3.at[i, 'SAP']), (df3.at[i, 'ID']), inplace=True)

print(df3)

当前执行结果

ID   Desc  QTY
0  100  Test1    1
1  200  Test2    7
2  300  Test3    1
3  400  Test4    3
4  500  Test5    4
5  600  Test6    9

    ID    Leg     SAP
0  100  165-8   142.0
1  200    NaN   655.0
2  300    NaN     NaN
3  400  21-56  4343.0
4  500   65-5     NaN
5  600  556-4   233.0

    ID   Desc  QTY    Leg     SAP
0  100  Test1    1  165-8   142.0
1  200  Test2    7    NaN   655.0
2  300  Test3    1    NaN     NaN
3  400  Test4    3  21-56  4343.0
4  500  Test5    4   65-5     NaN
5  600  Test6    9  556-4   233.0

    ID   Desc  QTY    Leg     SAP
0  100  Test1    1  165-8   142.0
1  200  Test2    7    200   200.0
2  300  Test3    1    200   200.0
3  400  Test4    3  21-56  4343.0
4  500  Test5    4   65-5   200.0
5  600  Test6    9  556-4   233.0

预期结果

ID   Desc  QTY    Leg     SAP
0  100  Test1    1  165-8   142.0
1  200  Test2    7    200   655.0
2  300  Test3    1    300   300.0
3  400  Test4    3  21-56  4343.0
4  500  Test5    4   65-5   500.0
5  600  Test6    9  556-4   233.0

问题原因

df.replace()方法默认会替换整个DataFrame中所有匹配的值,而非仅当前行的目标值。第一次循环(i=1)时,会把全表所有NaN替换成200,后续循环里已无NaN可处理,导致所有原NaN都变成第一个被处理的ID值。同时循环判断逻辑有漏洞:仅当Leg为NaN时才执行替换,会漏掉Leg非NaN但SAP为NaN的行(如i=4)。


解决方案

方法一:使用Pandas向量化操作(推荐)

用fillna()针对指定列按行匹配填充,效率远高于循环:

import pandas as pd
import numpy as np

df1 = pd.read_csv("df1.csv")
df2 = pd.read_csv("df2.csv")

df3 = pd.merge(df1, df2, on='ID', how='left')

# 用对应行ID填充Leg和SAP的NaN
df3['Leg'] = df3['Leg'].fillna(df3['ID'].astype(str))  # Leg是字符串类型,ID转字符串匹配格式
df3['SAP'] = df3['SAP'].fillna(df3['ID'])  # SAP是数值型,直接用ID填充

print(df3)

说明

  • fillna()可接收Series作为填充值,自动按行匹配,仅修改目标列的NaN,不影响其他列。
  • 类型匹配:Leg列是字符串格式,需把数值型ID转为字符串再填充;SAP列是数值型,直接用ID填充即可。

方法二:修正循环写法(不推荐)

若必须用循环,直接定位单元格赋值,而非使用replace():

import pandas as pd
import numpy as np

df1 = pd.read_csv("df1.csv")
df2 = pd.read_csv("df2.csv")

df3 = pd.merge(df1, df2, on='ID', how='left')

C = len(df3.index)

for i in range(C):
    # 单独判断并替换Leg列的NaN
    if pd.isnull(df3.at[i, 'Leg']):
        df3.at[i, 'Leg'] = str(df3.at[i, 'ID'])
    # 单独判断并替换SAP列的NaN
    if pd.isnull(df3.at[i, 'SAP']):
        df3.at[i, 'SAP'] = df3.at[i, 'ID']

print(df3)

说明

  • df.at[i, '列名']精准定位单元格,赋值仅修改目标位置,不会影响全表。
  • 分开判断Leg和SAP的NaN情况,避免遗漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 06:50:26