Pandas如何按id分组查找DataFrame列最近非零值填充0值
实现方法
需求规则
待处理的示例DataFrame结构如下:
id number 1 5 1 0 1 0 1 2 2 0 3 1
填充规则:
- 按
id字段分组 - 0值优先找同组内当前行之后最近的非零值填充(和示例要求匹配:id=1组内第二、第三行0填充为2)
- 后面没有非零值的,找同组内当前行之前最近的非零值填充
- 前后都找不到非零值的(如id=2全组只有0),保留原始0值
代码实现
pandas内置的分组填充函数可以直接实现该逻辑,步骤如下:
- 将
number列的0值替换为NaN(pandas填充逻辑默认识别空值) - 按
id分组后先做向后填充bfill,匹配“优先找后面最近非零值”的要求 - 再做一次向前填充
ffill,处理后面无有效非零值的场景 - 最后把剩余未填充的空值(整组无有效非零值)填回0
完整可运行代码:
import pandas as pd import numpy as np # 构造示例数据 df = pd.DataFrame({ 'id': [1,1,1,1,2,3], 'number': [5,0,0,2,0,1] }) # 核心填充逻辑 df['number'] = df['number'].replace(0, np.nan) df['number'] = df.groupby('id')['number'].bfill().ffill() df['number'] = df['number'].fillna(0)
运行后输出结果完全匹配需求:
id number 0 1 5.0 1 1 2.0 2 1 2.0 3 1 2.0 4 2 0.0 5 3 1.0
扩展:严格双向最近填充
如果业务要求不区分前后方向,严格取和当前0值绝对距离最近的非零值填充(距离相等时默认取后面的值),可以用近邻插值方法实现,替换核心填充逻辑即可:
df['number'] = df['number'].replace(0, np.nan) df['number'] = df.groupby('id')['number'].transform( lambda x: x.interpolate(method='nearest') ).ffill().bfill().fillna(0)
该逻辑下id=1组的填充结果为[5,5,5,2],即第一个0因为距离前面的5更近,会被填充为5。
内容的提问来源于stack exchange,提问作者nena
相关产品推荐
相关产品推荐

