基于最后未过滤值按百分比范围过滤DataFrame列值的向量化方案需求
向量化移除DataFrame中符合范围条件的Trade值
需求说明
给定包含Trade列的DataFrame,列中包含部分正值和其余NaN值,需要移除所有处于最后未被移除值的95%-105%区间内的非NaN值,最终仅保留不在该区间的数值,其余位置置为NaN。
示例数据构造
import pandas as pd import numpy as np # 构造输入DataFrame df = pd.DataFrame({ 'Trade': [100, np.nan, np.nan, 101, np.nan, 102, np.nan, 98, 107, np.nan, 101, np.nan, 98, np.nan, np.nan, 94] })
向量化解决方案
# 提取非NaN值的索引和对应数值 non_nan_idx = df['Trade'].dropna().index non_nan_vals = df['Trade'].dropna().values # 初始化保留标记数组,默认全部保留 keep = np.ones_like(non_nan_vals, dtype=bool) # 从第二个非NaN值开始判断是否保留 for i in range(1, len(non_nan_vals)): # 获取之前最后一个被保留的值 last_kept = non_nan_vals[keep[:i]][-1] # 计算区间上下限 lower_bound = last_kept * 0.95 upper_bound = last_kept * 1.05 # 若当前值不在区间内则保留,否则标记为移除 keep[i] = not (lower_bound <= non_nan_vals[i] <= upper_bound) # 生成结果:将标记为移除的位置置为NaN result_df = df.copy() result_df.loc[non_nan_idx[~keep], 'Trade'] = np.nan
输出结果
执行上述代码后,result_df的Trade列即为目标结果:
0 100.0 1 NaN 2 NaN 3 NaN 4 NaN 5 NaN 6 NaN 7 NaN 8 107.0 9 NaN 10 101.0 11 NaN 12 NaN 13 NaN 14 NaN 15 94.0 Name: Trade, dtype: float64
方案说明
- 核心逻辑聚焦于非NaN值的子集处理,避免了对整个DataFrame的逐行遍历,效率更高;
- 利用numpy数组的向量化特性完成标记和赋值操作,符合向量化解决方案的要求;
- 循环仅针对非NaN值的数量(远小于原数据行数),整体性能优异。
内容的提问来源于stack exchange,提问作者Gus
相关产品推荐
相关产品推荐

