Pandas筛选含'word'不含'not'行时触发float不可迭代TypeError
问题描述
现有如下结构的DataFrame:
WARNSPEAK4 WARNSIGN_DTL 1 1.0 word bla bla bla... 2 nan words do not contain... 3 nan word bla bla.. 4 1.0 word bla bla.. 5 nan no relation bla bla..
需要筛选出WARNSPEAK4为缺失值、WARNSIGN_DTL包含'word'但不包含'not'的行,编写的代码如下:
# WARNSPEAK4 결측치를 WARNSIGN_DTL칼럼에서 찾을 수 있는지 확인해봅시다 df3 = df[['WARNSPEAK4','WARNSIGN_DTL']] # take columns only we need df3[df3['WARNSPEAK4'].isnull() & df3['WARNSIGN_DTL'].str.contains('word',na=False) & df3['WARNSIGN_DTL'].apply(lambda x: 'not' not in x)]
执行后触发错误:
TypeError: argument of type 'float' is not iterable
已确认WARNSIGN_DTL列为字符串类型,但仍出现该错误。
问题原因与解决办法
原因
即便你认为列是字符串类型,WARNSIGN_DTL列的 dtype 大概率是object,其中可能混入了float类型的NaN值(Pandas中字符串列出现缺失时,会自动将列转为object类型,并存入float类型的NaN)。当apply的lambda函数遇到NaN时,执行'not' not in x会报错——float类型无法被迭代判断是否包含子串。
解决办法
放弃使用apply,改用Pandas的str.contains方法配合取反操作,该方法可以通过na参数统一处理空值,避免类型错误:
# 提取需要的列 df3 = df[['WARNSPEAK4','WARNSIGN_DTL']] # 构建筛选条件 filter_condition = ( df3['WARNSPEAK4'].isnull() & df3['WARNSIGN_DTL'].str.contains('word', na=False) & ~df3['WARNSIGN_DTL'].str.contains('not', na=False) ) # 应用筛选条件 result = df3[filter_condition]
代码说明
~符号用于对str.contains的结果取反,表示不包含指定子串;na=False表示将NaN值视为不满足条件,不会触发类型错误;- 链式条件判断逻辑清晰,性能比
apply更优(Pandas的str方法是向量化操作,比逐行apply效率高)。
内容的提问来源于stack exchange,提问作者Joshua Chung
相关产品推荐
相关产品推荐

