如何在Pandas中按行条件对指定单元格应用str.zfill函数?
解决Pandas中按条件为指定列添加前导零的问题
需求回顾
你想要在excodes这个DataFrame里实现:当LOB_SVC_CD列的值为"MTG"时,给PS_CD列补前导零到5位;其他情况保持PS_CD原有值不变,既可以创建新列,也可以直接修改原列。
正确实现方案
首先要确保PS_CD是字符串类型(如果原本是数字,先执行转换:excodes['PS_CD'] = excodes['PS_CD'].astype(str)),下面是几种简洁靠谱的实现方式:
1. 创建新列code(最推荐)
用np.where是最直观的方式,它会逐行判断条件,返回对应的值:
import numpy as np import pandas as pd excodes['code'] = np.where( excodes['LOB_SVC_CD'] == 'MTG', excodes['PS_CD'].str.zfill(5), excodes['PS_CD'] )
2. 用Pandas原生的Series.where/Series.mask
where的逻辑是满足条件时保留原数值,不满足时替换,因此需要反转条件:
excodes['code'] = excodes['PS_CD'].where( excodes['LOB_SVC_CD'] != 'MTG', excodes['PS_CD'].str.zfill(5) )
mask的逻辑和where相反(满足条件时替换),写法更直接:
excodes['code'] = excodes['PS_CD'].mask( excodes['LOB_SVC_CD'] == 'MTG', excodes['PS_CD'].str.zfill(5) )
3. 直接修改原PS_CD列
如果不需要保留原数据,可以直接定位符合条件的行修改:
excodes['PS_CD'] = excodes['PS_CD'].astype(str) excodes.loc[excodes['LOB_SVC_CD'] == 'MTG', 'PS_CD'] = excodes.loc[excodes['LOB_SVC_CD'] == 'MTG', 'PS_CD'].str.zfill(5)
你之前尝试的方法里的问题
简单说下你踩的几个坑:
- 自定义函数用
apply时,错误地直接判断整个筛选后的DataFrame的布尔值,Pandas无法解析一个DataFrame的真假,应该针对每行的LOB_SVC_CD值做判断; - 带循环的函数存在语法错误(
for row(i) in column是非法写法),而且Pandas是矢量化操作,完全没必要手动循环; np.where中传入的mask是筛选后的DataFrame,而非布尔Series,导致形状不匹配报错;- Lambda表达式逻辑混乱,错误使用字符串索引,没有正确处理逐行判断的逻辑;
assign方法需要传入关键字参数(如code=xxx),直接传入Series不符合方法要求。
内容的提问来源于stack exchange,提问作者jaguar100
相关产品推荐
相关产品推荐

