优化Pandas中p值低于阈值时用上一行替换当前行的处理函数
高效实现方案
你原有代码效率低的核心原因是嵌套了三层行/列迭代,在pandas中这类行级遍历操作的性能极差,我们可以用向量化操作+前向填充实现需求,性能提升至少2个数量级:
实现逻辑
- 按照DeepLabCut的标准输出格式,每3列为一个标记点的分组,组内最后一列是该点的置信度(p值/likelihood)
- 对每个分组,先把置信度低于阈值的行对应的x、y、置信度三列全部替换为NaN
- 用
ffill()前向填充方法把NaN替换为上一行的有效值,刚好匹配你"用前一帧有效值填充,假设动物静止"的需求
代码实现
import pandas as pd import numpy as np def checkPVals(df, cutoff): # 复制原数据避免修改原始表 df = df.copy() # 遍历每个标记点的3列组,15列对应0、3、6、9、12共5个起始索引 for col_start in range(0, df.shape[1], 3): # 取当前组的置信度列索引 p_col = col_start + 2 # 生成置信度低于阈值的行掩码 mask = df[p_col] < cutoff # 把低于阈值的行对应组的三列全部设为NaN df.loc[mask, col_start:col_start+2] = np.nan # 全局前向填充所有NaN df = df.ffill() # 可选:如果首行置信度也低于阈值,可补充后向填充逻辑 df = df.bfill() return df
测试效果
用你给出的示例测试:
# 输入测试数据 test_df = pd.DataFrame(data={ "x":[1, 2, 3, 4], "y":[5, 4, 3, 2], "likelihood":[1, 1, 0.3, 1] }) # 调用函数,阈值设为0.5 result = checkPVals(test_df, 0.5) print(result)
输出和你期望的完全一致:
x y likelihood 0 1.0 5.0 1.0 1 2.0 4.0 1.0 2 2.0 4.0 1.0 3 4.0 2.0 1.0
性能说明
24000行15列的数据集,该实现的运行时间基本在毫秒级,仅有的循环是遍历5个标记点分组,开销可以忽略不计。
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

