Pandas中使用字典进行字符串替换失败的原因排查
字典形式的pandas replace方法为何失效?
问题场景
我有如下格式的DataFrame:
0 1 2 0 2022-09-01T01:30:00+00:00 2543.207 -365.0 1 2022-09-01T02:00:00+00:00 2479.386 -365.0 2 2022-09-01T02:30:00+00:00 2443.331 -361.0 3 2022-09-01T03:00:00+00:00 2412.743 -360.0 4 2022-09-01T03:30:00+00:00 2398.775 -369.0 ... ... ... 18577 2023-09-24T02:00:00+00:00 2573.602 -897.0 18578 2023-09-24T02:30:00+00:00 2538.401 -915.0 18579 2023-09-24T03:00:00+00:00 2490.902 -942.0 18580 2023-09-24T03:30:00+00:00 2480.652 -959.0 18581 2023-09-24T04:00:00+00:00 199.222 -147.0
需要对第0列做两个替换:把+00:00替换为空字符串,把T替换为空格,最终得到格式化后的时间列。
我尝试了多种字典形式的replace写法,比如:
frame[0] = frame[0].astype('str') frame[0] = frame[0].replace({'+00:00':'', 'T':' '})
frame = frame.replace({0:{"+00:00":"", "T":" "}})
这些写法都没报错,但完全没生效,返回的还是原DataFrame;而用str.replace链式调用却能正常工作:
frame[0] = frame[0].str.replace('T', ' ', regex = False) frame[0] = frame[0].str.replace('+00:00','', regex = False)
原因分析
核心问题出在pandasreplace方法的匹配逻辑上:
- 默认是整值匹配:不管是Series还是DataFrame的
replace方法,默认模式下只会匹配整个元素完全等于字典key的情况,而不是匹配元素内的子字符串。你要替换的T和+00:00都是元素里的子串,不是整个元素的值,所以默认模式下根本不会触发替换。 - 正则模式的坑:如果你设置
regex=True想开启子串匹配,+在正则表达式里是特殊字符(表示匹配前面字符1次或多次),直接写'+00:00'会被正则引擎解析错误,导致匹配失败。必须对+进行转义,写成'\+00:00'或者用原始字符串r'\+00:00'才能正确匹配。 - str.replace是专门的子串替换工具:
str.replace是pandas为字符串列提供的专属方法,默认(pandas 2.0+)regex=False时就是普通的子字符串匹配替换,不需要考虑整值匹配的问题,也不会把普通字符当作正则特殊字符处理,所以能直接生效。
正确的字典形式写法
如果想用字典形式完成替换,需要开启正则模式并转义特殊字符:
# 方法1:转义+号 frame[0] = frame[0].replace({'\+00:00':'', 'T':' '}, regex=True) # 方法2:用原始字符串避免转义 frame[0] = frame[0].replace({r'\+00:00':'', 'T':' '}, regex=True)
内容的提问来源于stack exchange,提问作者I hate coding
相关产品推荐
相关产品推荐

