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

使用iterrows填充DataFrame df_3时返回NaN的问题及解决

问题:Pandas按动态列名取值填充DataFrame返回NaN的解决办法

数据与需求

有两个DataFrame:

  • df_1 存储各届毕业生的分数,索引为日期:
import numpy as np
import pandas as pd

data_1 = {"Grad_22": [96, np.nan, np.nan], "Grad_23": [92, 97, np.nan], "Grad_24": [np.nan, 93, 95]}
df_1= pd.DataFrame(data_1)
df_1["DATE"] = pd.to_datetime(["2022-12-31","2023-12-31","2024-12-31"])
df_1.set_index("DATE", inplace=True)

输出的df_1:

Grad_22  Grad_23  Grad_24
DATE                                 
2022-12-31     96.0     92.0      NaN
2023-12-31      NaN     97.0     93.0
2024-12-31      NaN      NaN     95.0
  • df_2 存储每年对应的毕业生类别(Sr/Jr)与分数列的映射,索引同样为日期:
data_2 = {
    "Sr": ["Grad_22","Grad_23"],
    "Jr": ["Grad_23","Grad_24"]
}
df_2 = pd.DataFrame(data_2)
df_2["DATE"] = pd.to_datetime(["2022-12-31","2023-12-31"])
df_2.set_index("DATE", inplace=True)

输出的df_2:

Sr       Jr
DATE                         
2022-12-31  Grad_22  Grad_23
2023-12-31  Grad_23  Grad_24

需要用df_2的每行作为列名标签,从df_1中取值填充df_3:

data_3= {"Sr": [0, 0], "Jr": [0, 0]}
df_3 = pd.DataFrame(data_3)
df_3 ["DATE"] = pd.to_datetime(["2022-12-31","2023-12-31"])
df_3.set_index("DATE", inplace=True)

尝试用iterrows遍历赋值:

for index, row in df_2.iterrows():
    df_3.loc[index] = df_1.loc[index, row] 

期望得到:

Sr       Jr
DATE                         
2022-12-31  96.0  92.0
2023-12-31  97.0  93.0

但实际返回全NaN的df_3:

Sr       Jr
DATE               
2022-12-31 NaN NaN
2023-12-31 NaN NaN

原因分析

问题出在索引对齐逻辑上:当用row(Series类型)作为df_1的列索引时,返回的Series的索引是Grad_xx这类分数列名,而不是df_3的Sr/Jr列名。Pandas赋值时会严格对齐索引,两者索引不匹配,导致无法正确填充值,最终返回NaN。

比如当index=2022-12-31时,df_1.loc[index, row]返回的结果是:

Grad_22    96.0
Grad_23    92.0
Name: 2022-12-31 00:00:00, dtype: float64

这个Series的索引是Grad_22和Grad_23,和df_3的Sr/Jr列索引完全不匹配,所以赋值后只能填充NaN。

解决方法

方法1:修正循环赋值的索引匹配

在循环中提取值后,重新匹配df_3的列索引:

for index, row in df_2.iterrows():
    # 提取对应分数值,用df_3的列名作为新索引
    score_values = df_1.loc[index, row].values
    df_3.loc[index] = pd.Series(score_values, index=df_3.columns)

方法2:向量化操作(推荐,避免循环)

用apply按行处理,直接生成目标结构的DataFrame:

df_3 = df_2.apply(lambda x: df_1.loc[x.name, x], axis=1)

这里x.name是每行的日期索引,x是该行的列名映射,apply(axis=1)按行处理后会自动生成与df_2结构一致的结果,直接赋值给df_3即可。

方法3:使用lookup函数(Pandas 1.2+支持)

通过lookup直接定位对应位置的值:

df_3 = pd.DataFrame({
    col: df_1.lookup(df_2.index, df_2[col])
    for col in df_2.columns
})
df_3.index = df_2.index

以上三种方法都能得到期望的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 18:44:57