Pandas中用lambda正则替换返回函数而非结果的问题及解决
Pandas正则替换显示lambda函数的问题解决
问题场景
需要在Pandas DataFrame的任意字符串列中,将格式为XX/XX/ XXXX(空格固定在第二个/之后)的日期字符串去除空格,转为XX/XX/XXXX。使用df.replace配合正则表达式和lambda函数时,结果列显示的是lambda函数对象而非处理后的值,但单独使用re.sub能得到正确结果。
示例错误代码:
import pandas as pd import numpy as np import re technologies = { 'Courses':["Spark","PySpark","Hadoop",pd.NaT], 'Fee' :[20000,25000,26000,22000], 'Duration':['30day','40days',np.nan, None], 'Discount':[1000,2300,1500,1200], 'Date':["23/3/ 2022","99/5/ 34","7/7/ 2122","6/12/ 2024"], } indexes=['r1','r2','r3','r4'] df = pd.DataFrame(technologies,index=indexes) print(df.replace(r'(\d+/\d+/ \d+)', lambda x: x.group(1).replace(" ", ""), regex=True))
错误输出中Date列显示为<function <lambda> at 0x...>而非处理后的日期字符串。
原因分析
Pandas的DataFrame.replace与原生re.sub对替换函数的参数逻辑完全不同:
- 原生
re.sub的lambda函数接收的是正则匹配对象(Match Object),可以通过group()提取分组内容; - Pandas的
replace在regex=True模式下,传入的替换函数接收的是匹配到的完整字符串,而非Match对象。此时调用x.group(1)会引发逻辑错误,导致Pandas无法正确执行函数,最终将函数本身作为替换值返回。
修复方案
方法1:修改lambda函数适配Pandas逻辑
直接对传入的匹配字符串进行空格替换,无需依赖分组:
# 修正后的替换代码 result = df.replace(r'\d+/\d+/ \d+', lambda x: x.replace(" ", ""), regex=True) print(result)
正确输出:
Courses Fee Duration Discount Date r1 Spark 20000 30day 1000 23/3/2022 r2 PySpark 25000 40days 2300 99/5/34 r3 Hadoop 26000 NaN 1500 7/7/2122 r4 NaT 22000 None 1200 6/12/2024
方法2:使用applymap配合re.sub(通用场景)
遍历所有元素,仅对字符串类型执行替换,避免影响非字符串列:
def clean_date(s): if isinstance(s, str): # 直接替换"/ "为"/",更精准 return re.sub(r'/\s+', '/', s) return s result = df.applymap(clean_date) print(result)
这种方法适用于不确定哪些列包含目标格式的场景,兼容性更强。
方法3:针对已知字符串列使用str.replace
如果明确知道目标列(比如Date列),可以直接对列操作:
df['Date'] = df['Date'].str.replace(r'/\s+', '/', regex=True)
内容的提问来源于stack exchange,提问作者Learning from masters
相关产品推荐
相关产品推荐

