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

Pandas DataFrame.apply()运行不符合预期的原因及正确写法

pandas按条件修改列值异常问题排查与实现

问题根因

  • 你最初的apply写法存在核心逻辑错误:对sqft_living单列执行apply时,传入的函数会逐元素触发一次,你的数据集共21613行,函数就会被调用2万余次。但你在函数内部没有操作当前传入的单个元素,而是直接对整个grade列执行全量加值,相当于每遍历一行数据,就给所有行的grade统一加1或加2。
  • 异常数值的计算逻辑完全可追溯:数据集中超过99%的房源sqft_living大于400,每遍历到这类房源就给全列grade加2,累计遍历完成后全列grade累计加值超过4万,叠加原始grade的6-13的基础值,刚好得到你看到的8万量级结果,末尾数字和原始值一致就是累计加值没有改变个位数值的缘故。
  • 你修改为赋值+/-后得到全列-的结果并非逻辑正确,只是覆盖式赋值的巧合:最后一次函数调用时传入的sqft_living值大于400,直接将全列grade覆盖为-,前面所有次的赋值结果都被最后一次操作覆盖,才得到了统一的输出。

正确实现方式

方式1:严格使用DataFrame.apply()实现

注意apply需要作用在整个DataFrame上,指定axis=1按行遍历,函数接收单行数据作为参数,返回当前行修改后的grade值,禁止在函数内部直接操作全表:

def grade_adjust(row):
    sqft = row['sqft_living']
    if 0 < sqft < 400:
        return row['grade'] + 1
    elif sqft > 400:
        return row['grade'] + 2
    # sqft等于0或400的边界场景可根据业务需求调整返回值
    return row['grade']

housing['grade'] = housing.apply(grade_adjust, axis=1)

方式2:pandas向量化实现(推荐,性能远高于apply)

逐行apply本质是Python层循环,数据量大时性能很差,优先使用pandas原生的条件选择赋值,执行效率是apply的数十倍:

# 筛选sqft_living大于400的行,grade统一加2
gt400_mask = housing['sqft_living'] > 400
housing.loc[gt400_mask, 'grade'] += 2

# 筛选sqft_living在0-400区间的行,grade统一加1
lt400_mask = (housing['sqft_living'] > 0) & (housing['sqft_living'] < 400)
housing.loc[lt400_mask, 'grade'] += 1

也可以用numpy.where实现嵌套条件赋值,代码更简洁:

import numpy as np

housing['grade'] = np.where(
    (housing['sqft_living'] > 0) & (housing['sqft_living'] < 400),
    housing['grade'] + 1,
    np.where(
        housing['sqft_living'] > 400,
        housing['grade'] + 2,
        housing['grade']
    )
)

注意:原逻辑没有处理sqft_living等于400或等于0的边界场景,实际使用时需要根据业务规则补充对应逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 20:27:26