如何在Pandas DataFrame中查找所有非Latin1(ISO 8859-1)字符
报错原因
df.iterrows()返回的是(行索引, 行数据Series)二元组,你直接遍历row变量时,i会依次取到行索引、行Series对象,对Series直接执行if i:判断就会触发The truth value of a Series is ambiguous的错误。
非Latin1字符检测实现方案
不需要正则枚举所有Latin1字符,直接用编码校验逻辑即可实现,以下是两种可用方案:
方案1:修正原有循环逻辑
适合小数据量场景,修改你原有错误逻辑即可运行:
islatin1 = [] # 遍历所有列 for col in DF.columns: # 跳过非字符串类型列,减少无效判断 if DF[col].dtype != object: continue # 遍历行,正确接收索引和行数据 for idx, row in DF.iterrows(): current_val = row[col] # 跳过非字符串类型的值 if not isinstance(current_val, str): continue try: current_val.encode(encoding="latin-1", errors="strict") except UnicodeEncodeError: # 编码失败即为不符合Latin1规范的内容 islatin1.append([row['ID'], col, current_val]) Invalid_latin1 = pd.DataFrame(islatin1, columns=['ID', 'Bad_Column', 'Bad_Data'])
方案2:向量化实现
适合大数据量场景,性能远高于逐行遍历:
def is_latin1(val): # 非字符串类型默认判定为符合要求,可根据业务需求调整规则 if not isinstance(val, str): return True try: val.encode("latin-1", errors="strict") return True except UnicodeEncodeError: return False invalid_list = [] # 仅筛选字符串类型列做检测 for col in DF.select_dtypes(include='object').columns: # 批量生成不符合规则的行掩码 bad_mask = ~DF[col].apply(is_latin1) # 提取当前列的异常数据 bad_rows = DF.loc[bad_mask, ['ID', col]] for _, row in bad_rows.iterrows(): invalid_list.append([row['ID'], col, row[col]]) Invalid_latin1 = pd.DataFrame(invalid_list, columns=['ID', 'Bad_Column', 'Bad_Data'])
两种方案都是直接基于字符编码能力做校验,和Latin1编码的原生规则完全对齐,不会出现正则枚举遗漏的问题。
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

