如何实现Pandas中列表与列的不区分大小写匹配验证?
不区分大小写的DataFrame列值合法性验证方案
问题背景
现有一段Pandas代码用于验证DataFrame各列值是否属于对应valid字典指定的合法列表,但需要实现不区分大小写的匹配验证。用户尝试直接将valid转为小写列表时触发错误:TypeError: list indices must be integers or slices, not str。
错误原因
用户写的valid= [x.lower() for x in valid]是把字典当成可迭代对象遍历,默认会取出字典的键,最终得到的是键的小写列表。后续代码中valid[c.name]试图用列名(字符串)索引列表,自然会触发类型错误。
解决方案(无需修改原始数据大小写)
我们可以通过将合法值转为小写集合,同时在验证时把DataFrame的列值转为小写进行匹配,既保留原始数据的大小写,又实现不区分大小写的验证:
import pandas as pd data = [ ["Automotive", "Education", "Enterance", "Commercial"], ["Gas", "Hotels", "Access", " "], ["Healthcare", " ", "Video System", "Reseller"], ["automotive", "MINING", "access", "SMALL"], # 测试大小写不同的合法值 ] df_test = pd.DataFrame( data, columns=["Industry_US", "Industry_EU", "System Type", "Account Type"] ) valid = { "Industry_US": ["Automotive", "Retail", "Gas", "Other"], "Industry_EU": ["Real Estate", "Transport", "Mining"], "System Type": ["Access", "Video System"], "Account Type": ["Commercial", "Reseller", "Small"], } # 生成小写的合法值集合(集合查找效率高于列表) valid_lower = {col: {val.lower() for val in vals} for col, vals in valid.items()} # 生成掩码:值转小写后在合法集合中,或者是空字符串(空串视为合法) mask = df_test.apply(lambda c: c.str.lower().isin(valid_lower[c.name]) | c.eq(" ")) # 筛选并输出所有不合法的条目 for (row_idx, col_name), invalid_val in df_test.mask(mask).stack().items(): print(f'error found in row "{row_idx}", column "{col_name}": "{invalid_val}" is invalid')
代码说明
valid_lower:将原始valid字典中的每个合法值列表转为小写集合,集合的成员查找效率比列表更高,适合批量验证场景。mask生成:对每一列的所有值转小写后,判断是否在对应的小写合法集合中,同时保留空串的合法判断逻辑。- 错误输出:通过
mask过滤掉合法值,剩下的无效值通过stack()展开后遍历输出,显示的是原始数据的大小写形式。
内容的提问来源于stack exchange,提问作者user19702551
相关产品推荐
相关产品推荐

