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

基于索引用上方值填充NaN及按ID填充Pandas DataFrame NaN的方法

我来帮你搞定这两个Pandas里的NaN填充问题,都是日常数据清洗中非常常见的需求:

问题1:用上方前一个有效值填充NaN

在Pandas里,实现这个需求最直接的方式就是用fillna()方法,指定method='ffill'(全称forward fill,向前填充)。这个方法会沿着索引方向,把每个NaN替换成它上方(前一行)的第一个有效值。

举个简单的示例代码:

import pandas as pd
import numpy as np

# 构造测试数据
df = pd.DataFrame({'数值列': [10, np.nan, 30, np.nan, np.nan, 60]})
# 执行向前填充
df['填充后列'] = df['数值列'].fillna(method='ffill')
print(df)

运行后输出结果:

数值列  填充后列
0  10.0   10.0
1   NaN   10.0
2  30.0   30.0
3   NaN   30.0
4   NaN   30.0
5  60.0   60.0

补充几个实用细节:

  • 如果想对整个DataFrame的所有列都执行这个操作,直接用df.fillna(method='ffill')即可
  • 如果数据开头就有NaN,ffill不会填充它(因为前面没有有效值),如果需要处理这种情况,可以结合向后填充bfill,比如df.fillna(method='ffill').fillna(method='bfill')
  • 可以用limit参数限制连续填充的NaN数量,比如df['数值列'].fillna(method='ffill', limit=2)只会填充最多2个连续的NaN
问题2:按ID分组,用对应ID的有效值填充NaN

这个场景需要先按ID分组,再在每个组内完成填充。针对你给出的示例(每个ID只有一个有效值),这里有几种简单且实用的实现方式:

方法1:分组后用向前填充

因为每个ID的第一个值就是有效值,后面全是NaN,分组后用ffill就能快速覆盖所有同组的NaN:

import pandas as pd
import numpy as np

# 你的示例数据
df = pd.DataFrame({
    'ID': [1,1,1,1,1,2,2,2,2,3,3,3],
    'COL': [23, np.nan, np.nan, np.nan, np.nan, 21, np.nan, np.nan, np.nan,25,np.nan,np.nan]
})

# 分组执行向前填充
df['COL'] = df.groupby('ID')['COL'].ffill()
print(df)

方法2:用transform取组内有效值填充(更健壮)

如果你的实际数据中,有些ID的有效值不是在第一行(比如中间行有有效值),可以用transform获取组内的第一个非NaN值,来填充整个组的NaN:

df['COL'] = df.groupby('ID')['COL'].transform(lambda x: x.fillna(x.dropna().iloc[0]))

这个方法不管有效值在组内的哪个位置,只要组内有至少一个有效值,就能完成填充。

方法3:先提取ID对应有效值再合并填充

如果你需要单独保存每个ID对应的有效值,也可以先提取出这部分数据,再合并回原DataFrame填充:

# 提取每个ID的第一个有效值
id_valid_values = df.groupby('ID')['COL'].first().reset_index()
# 合并回原数据并填充NaN
df = df.merge(id_valid_values, on='ID', suffixes=('', '_有效值'))
df['COL'] = df['COL'].fillna(df['COL_有效值'])
# 移除临时列
df.drop('COL_有效值', axis=1, inplace=True)

以上几种方法都能得到你预期的结果:所有同ID的COL列NaN都会被填充为该ID对应的有效值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:12:17