Python分位数选择函数转Lambda函数运行异常排查
分位数标记Lambda函数异常排查
现存问题
你的代码共有3类问题,包含语法错误、执行顺序错误和核心逻辑错误,其中逻辑错误是运行效果不符合预期的根因:
- 语法错误:lambda表达式末尾多了1个多余的右括号,会直接触发语法解析失败
- 执行顺序错误:调用
df.apply()的代码写在df对象初始化之前,运行时会直接报df未定义的名称错误 - 核心逻辑错误:90分位值是基于整个列的全量数据计算的固定阈值,但你写在apply里的分位数计算逻辑和apply的传参机制冲突:
若保持默认按列遍历(
axis=0),传入lambda的是整列数据,x >= 分位值返回的是布尔序列,无法作为if的单判断条件,会触发真值歧义报错;
若改成按行遍历(axis=1),传入lambda的是单个元素值,对单个值计算分位数返回值就是元素本身,x >= 自身永远成立,所有行都会被标记为'yes',完全不符合预期。
正确实现
不需要用apply做逐行循环,pandas的向量化运算效率更高,代码也更简洁:
import pandas as pd import numpy as np # 优先初始化DataFrame df = pd.DataFrame({'tm': [263, 257, 263, 268, 268,259, 265, 263, 256, 263, 264, 268, 268, 263, 262, 260, 262, 235, 263, 264, 264]}) # 一次性计算全列90分位阈值 q90_threshold = np.quantile(df['tm'], 0.9) # 向量化判断生成标记列 df['tag'] = np.where(df['tm'] >= q90_threshold, 'yes', 'no')
如果你一定要用lambda写法(性能差,仅做语法演示),需要提前把分位阈值计算好,不要在逐元素调用的lambda里重复计算:
q90_threshold = np.quantile(df['tm'], 0.9) df['tag'] = df['tm'].apply(lambda x: 'yes' if x >= q90_threshold else 'no')
针对你提供的样例数据,计算得到的90分位值为268,所有tm值等于268的行会被标记为'yes',其余标记为'no',和预期逻辑一致。
内容的提问来源于stack exchange,提问作者GSA
相关产品推荐
相关产品推荐

