You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pandas根据另一列阈值分类赋值时结果异常问题排查

问题场景

我的数据形式如下:
screenshot of data

我编写了如下脚本,用于为RP8_Recruise列赋值:规则为NEAR_DIST小于等于100米时赋值为"Y",同时给RP_8RecrType列赋值为"PD";NEAR_DIST大于100米时RP8_Recruise赋值为"N",RP_8RecrType设为空值。

nrows = plots_dist_joined.shape[0]

for i in range(0, nrows):
    
    # 距离干扰采伐区在目标范围内的样地
    if (plots_dist_joined.iloc[i,9] < 100) | (plots_dist_joined.iloc[i,9] == 100):
        plots_dist_joined["RP_"+reporting_period+"Recruise"] = "Y"
        plots_dist_joined["RP_"+reporting_period+"RecrType"] = "PD"
    
    # 距离干扰采伐区不在目标范围内的样地
    else:
        plots_dist_joined["RP_"+reporting_period+"Recruise"] = "N"
        plots_dist_joined["RP_"+reporting_period+"RecrType"] = np.nan

运行代码后RP_8Recruise列所有值都被填充为"N",但数据中实际存在NEAR_DIST小于100米的记录(对应ID为59197、40、84、92、132),无法定位问题。


问题根因

代码逻辑错误出在赋值粒度上:

  • 循环内每次写plots_dist_joined[列名] = 值的操作,是对整列所有行统一赋值,不是只修改当前遍历到的第i行
  • 循环逐行执行时,前面对符合条件行设置的"Y",会被后续行的判断结果覆盖。如果最后一行的NEAR_DIST大于100,整列就会被最终覆盖为"N",之前所有的"Y"赋值都会被冲掉
  • 额外风险:用硬编码索引iloc[i,9]取NEAR_DIST列,一旦列顺序变动就会取错字段,导致判断完全失效

修复方案

pandas做这类条件赋值优先用向量化操作,不需要写逐行循环,运行速度更快也不会出现整列覆盖的问题:

import numpy as np
import pandas as pd

# 提前定义列名,避免重复拼接字符串
# 建议直接写NEAR_DIST的实际列名替代硬编码索引,减少出错概率,比如dist_col = "NEAR_DIST"
dist_col = plots_dist_joined.columns[9]
recruise_col = f"RP_{reporting_period}Recruise"
recrtype_col = f"RP_{reporting_period}RecrType"

# 构造判断条件:距离<=100米
within_dist_mask = plots_dist_joined[dist_col] <= 100

# 分条件赋值
plots_dist_joined.loc[within_dist_mask, recruise_col] = "Y"
plots_dist_joined.loc[within_dist_mask, recrtype_col] = "PD"
plots_dist_joined.loc[~within_dist_mask, recruise_col] = "N"
plots_dist_joined.loc[~within_dist_mask, recrtype_col] = np.nan

如果一定要保留逐行循环写法(数据量大于1万行时速度会比向量化写法慢几十到上百倍,不推荐),需要把赋值目标指定为当前行:

nrows = plots_dist_joined.shape[0]
recruise_col = f"RP_{reporting_period}Recruise"
recrtype_col = f"RP_{reporting_period}RecrType"
# 提前获取列索引,避免循环内重复计算
recruise_col_idx = plots_dist_joined.columns.get_loc(recruise_col)
recrtype_col_idx = plots_dist_joined.columns.get_loc(recrtype_col)

for i in range(nrows):
    dist_val = plots_dist_joined.iloc[i, 9]
    if dist_val <= 100:
        plots_dist_joined.iloc[i, recruise_col_idx] = "Y"
        plots_dist_joined.iloc[i, recrtype_col_idx] = "PD"
    else:
        plots_dist_joined.iloc[i, recruise_col_idx] = "N"
        plots_dist_joined.iloc[i, recrtype_col_idx] = np.nan

结果校验

赋值完成后可以通过两个方式核对结果:

  1. 统计符合距离条件的行数和赋值为"Y"的行数,二者相等则逻辑正确
# 距离<=100的行数
print(plots_dist_joined[plots_dist_joined.iloc[:,9] <= 100].shape[0])
# Recruise列为Y的行数
print(plots_dist_joined[plots_dist_joined[recruise_col] == "Y"].shape[0])
  1. 单独筛选提到的几个ID的记录,检查对应列的赋值是否符合预期。

内容的提问来源于stack exchange,提问作者Gloria Desanker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 12:19:51