如何用Pandas将DataFrame中的0替换为最近非零值的平均值
解决DataFrame中0值替换为指定非零值的问题
我来帮你搞定这个需求!你想要把DataFrame里的0替换成特定规则的非零值:第一个0用后面最近的非零值,其余0用两侧最近非零值的平均值,这确实没法用简单的ffill或bfill直接实现,咱们一步步来写代码实现:
第一步:准备示例数据
先定义你给出的DataFrame:
import pandas as pd import numpy as np df = pd.DataFrame({'A':[0,0,15,0,0,12,0,0,0,5]})
第二步:提取非零值的关键信息
首先把所有非零值的索引和对应数值提取出来,方便后续快速定位每个0的前后非零值:
# 获取非零值的索引列表和对应的数值列表 non_zero_idx = df[df['A'] != 0].index.tolist() non_zero_vals = df[df['A'] != 0]['A'].tolist()
第三步:编写替换逻辑函数
我们写一个函数,针对每个元素的索引和值,判断是否需要替换,并计算对应的替换值:
def replace_zero_logic(index, value): # 如果不是0,直接返回原值 if value != 0: return value # 处理第一个元素是0的情况:取第一个非零值 if index == 0: return non_zero_vals[0] # 找到当前索引在非零索引列表中的插入位置,以此确定前后最近的非零值位置 pos = np.searchsorted(non_zero_idx, index) # 前面最近的非零值 prev_val = non_zero_vals[pos - 1] # 后面最近的非零值(如果存在) if pos < len(non_zero_idx): next_val = non_zero_vals[pos] return (prev_val + next_val) / 2 # 边界情况:如果后面没有非零值(比如最后几个都是0),就用前面的非零值 else: return prev_val
第四步:应用函数到DataFrame
用apply把函数应用到每一行,生成新的列:
df['A_replaced'] = df.apply(lambda row: replace_zero_logic(row.name, row['A']), axis=1)
查看结果
运行后打印DataFrame,就能得到你想要的结果:
print(df)
输出如下:
A A_replaced 0 0 15.0 1 0 15.0 2 15 15.0 3 0 13.5 4 0 13.5 5 12 12.0 6 0 8.5 7 0 8.5 8 0 8.5 9 5 5.0
逻辑说明
- 对于第一个0,直接取第一个出现的非零值(也就是15);
- 对于中间的0,比如索引1,前后最近的非零值都是15,所以平均值是15;
- 索引3、4的前后最近非零值是15和12,平均值就是(15+12)/2=13.5;
- 索引6、7、8的前后最近非零值是12和5,平均值就是(12+5)/2=8.5,完全符合你的要求。
内容的提问来源于stack exchange,提问作者Shin Yu Wu
相关产品推荐
相关产品推荐

