Python pandas使用replace替换列值时所有行被误更新问题
问题原因
两个问题共同导致了这个bug:
- 正则里表示数字范围的横杠用错了:你代码里写的
‐是Unicode特殊连字符,不是ASCII标准半角减号-,因此[^0‐9]根本无法识别「0到9的数字范围」,实际匹配规则变成了「匹配所有不是'0'、不是特殊连字符、不是'9'的字符」——也就是说1、2、3、4、5、6、7、8这些合法数字也会被判定为需要替换的内容。 - 就算把横杠改对,现有逻辑也不符合需求:
Series.replace在正则模式下默认替换匹配到的子串,而非判断整个值是否非法。比如值为12a3时,改对正则后只会把a替换成0得到1203,做不到「只要含非数字字符整个值置0」的效果。
修正方案
不要自己写正则做数值判断,用pandas内置的pd.to_numeric是最稳妥、最不容易出问题的写法:
- 调用
pd.to_numeric转换money列,传入errors='coerce'参数,所有无法转成数字的值会自动转成空值NaN - 用
fillna(0)把空值统一填充为0,最后转成int类型更符合数值字段的预期
修正后的完整代码:
import pandas as pd df = pd.read_csv("./input.csv", sep=",") df['money'] = pd.to_numeric(df['money'], errors='coerce').fillna(0).astype(int) df.to_csv("./output.csv", index=False)
如果你坚持要用正则实现,需要先把横杠换成半角减号,同时加上首尾匹配符判断整个字符串是否全为数字,再做替换:
df['money'] = df['money'].replace(to_replace=r'^.*[^0-9].*$', value=0, regex=True)
这种写法鲁棒性很差,遇到带小数点、正负号的合法数字很容易误判,不推荐使用。
运行代码后输出的output.csv内容完全符合预期:
name,money Dan,200 Jimmy,0 Alice,15 Deborah,30
内容的提问来源于stack exchange,提问作者ForeverStudent
相关产品推荐
相关产品推荐

