Pandas中检查字符串列表匹配指定前缀返回None问题排查
问题修正:检查DataFrame字符串列表是否包含指定前缀的元素
错误原因分析
- 传参错误:在
frame.apply的lambda里,你传入了整个frame['place_holder']列,而非当前行的列表元素,导致value_check函数没有处理每行的具体数据。 - 缺少返回值:
value_check函数仅在满足条件时返回True,不满足时无返回语句,默认返回None,这也是所有行返回None的直接原因。
修正后的基础实现
import pandas as pd frame = pd.DataFrame({'a' : ['111,222,2333,444', '211,44', '222,333,444','666,777','555']}) frame['place_holder'] = frame['a'].apply(lambda x: x.upper().split(',')) codes = ['55', '33'] def value_check(x, codes): # 明确返回True/False return any(str(item).startswith(tuple(codes)) for item in x) # 传入当前行的place_holder而非整个列 frame['result'] = frame.apply(lambda x: value_check(x['place_holder'], codes), axis=1) print(frame)
执行后会得到预期结果:第3行(索引2)和第5行(索引4)的result为True。
更高效的向量化实现(推荐)
避免使用apply(大数据量下效率较低),直接用Pandas字符串方法结合正则匹配:
import pandas as pd frame = pd.DataFrame({'a' : ['111,222,2333,444', '211,44', '222,333,444','666,777','555']}) codes = ['55', '33'] # 构建正则表达式:匹配以任意指定前缀开头的元素(支持逗号分隔的列表) pattern = fr'^(.*,)?({"|".join(codes)})' # case=False 忽略大小写,和原代码的upper()效果一致 frame['result'] = frame['a'].str.contains(pattern, case=False) print(frame)
正则说明:^(.*,)?匹配元素前的任意内容加逗号(或无前置内容),{"|".join(codes)}匹配任意指定前缀,确保列表中存在符合条件的元素。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

