如何将时间序列DataFrame中的掩码区间扩展至相邻行?
问题:如何扩展时间序列中的掩码至相邻行?
我有一个包含坏测量值区间的时间序列数据集,使用df.mask()屏蔽了超出阈值的坏测量值进行数据清洗。但担心坏值的相邻行也受影响(只是未超出阈值),为稳妥起见希望同时屏蔽这些相邻区间。例如:
>>> df seconds value 0 1 5 1 2 2 2 3 -1 3 4 -3 4 5 2 5 6 4 6 7 6 >>> # 仅屏蔽负值(坏测量值) >>> df["good value"] = df["value"].mask(lambda x: x < 0) >>> df seconds value good value 0 1 5 5.0 1 2 2 2.0 # <--- 希望同时屏蔽该行 2 3 -1 NaN 3 4 -3 NaN 4 5 2 2.0 # <--- 希望同时屏蔽该行 5 6 4 4.0 6 7 6 6.0
如何将任意掩码值块扩展至其1行或2行相邻行?
解决方案
方法1:利用shift()手动扩展掩码
先创建初始掩码,再通过shift()将掩码的前N行和后N行也标记为需要屏蔽的范围,最后合并所有掩码条件:
import pandas as pd df = pd.DataFrame({ "seconds": [1,2,3,4,5,6,7], "value": [5,2,-1,-3,2,4,6] }) # 1. 创建初始掩码:标记所有负值(坏值) mask = df["value"] < 0 # 2. 扩展掩码:覆盖初始掩码的前1行和后1行 expanded_mask = mask | mask.shift(1, fill_value=False) | mask.shift(-1, fill_value=False) # 3. 应用扩展后的掩码 df["good value"] = df["value"].mask(expanded_mask) print(df)
输出结果:
seconds value good value 0 1 5 5.0 1 2 2 NaN 2 3 -1 NaN 3 4 -3 NaN 4 5 2 NaN 5 6 4 4.0 6 7 6 6.0
如果需要扩展前后各2行,只需增加多组shift():
expanded_mask_2rows = mask | mask.shift(1, fill_value=False) | mask.shift(-1, fill_value=False) | mask.shift(2, fill_value=False) | mask.shift(-2, fill_value=False)
方法2:用滚动窗口(rolling)覆盖连续坏值块
针对连续的坏值区间,使用中心滚动窗口自动覆盖相邻行,窗口大小设为2*N+1即可扩展前后N行:
# 用大小为3的中心窗口(覆盖前后1行)创建扩展掩码 expanded_mask_rolling = mask.rolling(window=3, center=True, min_periods=1).max().astype(bool) df["good value rolling"] = df["value"].mask(expanded_mask_rolling)
方法3:用SciPy二进制膨胀实现灵活扩展
如果需要更复杂的扩展规则(比如非对称范围),可以用scipy.ndimage.binary_dilation进行二进制膨胀操作:
from scipy.ndimage import binary_dilation # 定义结构元素:[1,1,1] 表示扩展前后各1行,改成[1,1,1,1,1]则扩展前后各2行 structure = [1,1,1] expanded_mask_dilation = binary_dilation(mask.values, structure=structure).tolist() df["good value dilation"] = df["value"].mask(expanded_mask_dilation)
内容的提问来源于stack exchange,提问作者drs
相关产品推荐
相关产品推荐

