如何使用插值法清理DataFrame单列中的异常值
你现有方案的可优化点:
- 逐行遍历+自定义循环查找非空值的逻辑性能极低,当DataFrame数据量超过万行时耗时会非常明显
- 自定义的
while_non_nan函数存在索引越界的潜在风险,比如当连续空值出现在序列末尾时容易触发异常 - 你需要的连续空值加权插值、首尾空值填充的逻辑,pandas已经内置了成熟的向量化实现,不需要手动造轮子。
更简便的实现方式完全基于pandas内置方法即可实现,代码如下:
import pandas as pd import numpy as np # 异常值替换为NaN,和你原有逻辑保持一致 evoli.loc[(evoli['T1'] <= 0) | (evoli['T1'] >= 1100), 'T1'] = np.nan # 线性插值处理中间段的连续空值,自动按前后非空值计算加权均值,完全匹配你的需求 evoli['T1'] = evoli['T1'].interpolate(method='linear') # 处理序列开头的空值用后向填充,末尾的空值用前向填充,和你给的示例输出完全对齐 evoli['T1'] = evoli['T1'].bfill().ffill()
你可以用你给出的示例验证效果:
test_series = pd.Series([np.nan, 0, 1, 2, np.nan, 4, np.nan, np.nan, 7, np.nan]) test_series = test_series.interpolate(method='linear').bfill().ffill() print(test_series.tolist()) # 输出:[0.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 7.0]
这个方案的优势非常明显:全向量化操作没有自定义循环,处理百万行级数据的耗时也能控制在毫秒级;内置方法已经做了边界异常处理,不会出现索引越界问题;代码精简可读性高,后续维护成本极低。
内容的提问来源于stack exchange,提问作者coyote
相关产品推荐
相关产品推荐

