Pandas根据列数值生成分类列遇逻辑错误,请求排查优化
问题排查与优化方案
原代码核心问题
- 判断列错误:你要基于
difference列的值计算score,但代码里错误地用score列作为判断条件——比如初始score为100的行,不管difference是-0.8还是其他值,都会被判定为>1,从而赋值为100,这就是你看到的“误将-0.8识别为大于1的值”的原因。 - 赋值顺序颠倒:判断条件没有从严格到宽松排列,比如先处理
>0.25再处理>0.5,会导致原本符合>0.5的行先被设为55,随后又被覆盖成65,逻辑完全混乱。 - DataFrame混用:代码里交替使用
df和df2,容易导致数据引用错误,出现非预期结果。
修正后的np.where实现
先修正判断列,再调整判断顺序(从严格到宽松):
import numpy as np import pandas as pd # 基于difference列计算score,顺序从严格到宽松 df2['score'] = np.where(df2['difference'] > 1, 100, np.where(df2['difference'] > 0.8, 85, np.where(df2['difference'] > 0.5, 65, np.where(df2['difference'] > 0.25, 55, np.where(df2['difference'] == -1, 0, np.where(df2['difference'] < -0.9, 5, np.where(df2['difference'] < -0.5, 25, np.where(df2['difference'] < -0.25, 30, df2['score']))))) ))
自定义函数+apply实现(更易读)
如果觉得嵌套np.where太繁琐,可以用自定义函数,逻辑更清晰:
def calculate_score(diff): if diff > 1: return 100 elif diff > 0.8: return 85 elif diff > 0.5: return 65 elif diff > 0.25: return 55 elif diff == -1: return 0 elif diff < -0.9: return 5 elif diff < -0.5: return 25 elif diff < -0.25: return 30 else: return df2['score'] # 返回原score值或自定义默认值 df2['score'] = df2['difference'].apply(calculate_score)
更高效的pd.cut实现(适合批量区间分类)
如果是连续区间的分类,用pd.cut更高效,尤其处理大数据集:
# 定义区间边界和对应得分 bins = [-np.inf, -0.9, -0.5, -0.25, 0.25, 0.5, 0.8, 1, np.inf] labels = [5, 25, 30, 55, 65, 85, 100] # 先处理==-1的特殊值,再用pd.cut处理其他区间 df2['score'] = np.where(df2['difference'] == -1, 0, pd.cut(df2['difference'], bins=bins, labels=labels, include_lowest=True)) # 转换为数值类型(pd.cut默认返回category类型) df2['score'] = df2['score'].astype(int)
内容的提问来源于stack exchange,提问作者Opper_Draak
相关产品推荐
相关产品推荐

