Pandas apply取kst列首个非空值前两位的实现问题及方案咨询
问题原因
- 状态变量失效:你把
found、first_kst定义在get_id函数内部,apply按行处理时每一行都会重新执行函数、重置变量,完全无法保留上一行的处理状态,不可能实现“找到首个非空值就停止搜索”的逻辑。 - 非空判断错误:Pandas里的空值
np.nan直接做if row.kst:判断时,布尔值为True,所以空值也会进入分支,才会出现日志打印first_kst : nan的情况。 - 返回值缺失:当行不满足
art == "R" and ust == "J"条件时,函数没有显式返回值,会默认返回None,导致结果列出现异常值。
正确实现方案
根据你描述的需求,分两种常见场景给出实现,都不需要用低效的行遍历apply:
场景1:全表只取kst列第一个非空值,所有满足条件的行统一用这个值的前2位
import pandas as pd # 第一步:提取kst列第一个非空值(自动跳过nan、空字符串) first_kst = df_merged['kst'].dropna().loc[lambda x: x.str.strip() != ''].iloc[0] kst_prefix = first_kst[:2] # 第二步:给满足条件的行赋值 df_merged['id'] = pd.NA df_merged.loc[(df_merged['art'] == 'R') & (df_merged['ust'] == 'J'), 'id'] = kst_prefix
场景2:每个满足条件的行,取本行及之前所有行里kst的第一个非空值的前2位
import pandas as pd # 第一步:用前向填充补全kst的空值,每一行的填充值都是本行及之前最近的非空kst df_merged['kst_ffill'] = df_merged['kst'].ffill() # 第二步:给满足条件的行赋值前2位 df_merged['id'] = pd.NA df_merged.loc[(df_merged['art'] == 'R') & (df_merged['ust'] == 'J'), 'id'] = df_merged['kst_ffill'].str[:2] # 可选:删除临时辅助列 df_merged.drop('kst_ffill', axis=1, inplace=True)
如果确实需要用自定义函数实现跨行的状态记录,可以把状态变量定义在函数外部,或者用闭包实现,但性能远不如上面的向量化操作,不推荐。
内容的提问来源于stack exchange,提问作者x89
相关产品推荐
相关产品推荐

