Pandas调用DataFrame.query报错Unhashable type:'Series'
问题描述
- 正在开展约翰尼·德普与艾梅柏·希尔德相关推特情感分析工作,已提取2021年全时段相关推文数据,两位人物对应的Pandas DataFrame存储于
df_dict字典中。 - 运行预处理代码时程序抛出 Unhashable type: 'Series' 错误。
- 已知该类错误通常出现于字典搭配不可哈希键使用的场景,但单独测试单个字典键的运行场景时依然触发相同错误,暂时无法定位问题根源。
问题复现代码
预处理函数
import re def preprocess(df_dict, remove_rows, keep_rows): for key, df in df_dict.items(): print(key) initial_count = len(df_dict[key]) df_dict[key] = ( df # 文本统一转小写 .assign(Text=lambda x: x['Text'].str.lower()) # 保留提及目标人物的行 .query(f'Text.str.contains("{keep_rows[key]}")') # 删除提及其他无关人物的行 .query(f'~Text.str.contains("{remove_rows[key]}")') # 移除文本中所有URL .assign(Text=lambda x:x['Text'].apply(lambda s: re.sub(r'\w+:\/{2}[\d\w-]+(\.[\d\w-]+)*(?:(?:\/[^\s/]*))*', '', s))) ) final_count = len(df_dict[key]) print("%d tweets kept out of %d" % (final_count, initial_count)) return df_dict
函数调用逻辑
df_dict = { 'johnny depp': johnny_data, "amber heard": amber_data } remove_rows = { 'johnny depp': 'amber|heard|camila|vasquez|shannon|curry', "amber heard": 'johnny|depp|camila|vasquez|shannon|curry' } keep_rows = { 'johnny depp': 'johnny|depp', "amber heard": 'amber|heard' } df_test_data = preprocess(df_dict, remove_rows, keep_rows)
报错根源
错误来自query()方法的解析机制:使用f-string直接拼接字符串生成查询表达式时,pandas会优先将引号包裹的内容匹配为当前DataFrame的列名,解析过程中会误将传入的正则匹配规则识别为Series对象,最终触发不可哈希类型报错。
修复方案
不要通过f-string拼接查询语句,提前将待匹配的正则规则存为局部变量,在query()中通过@符号引用外部Python变量即可,这种写法也能避免特殊字符导致的解析异常。修复后的预处理函数如下:
import re def preprocess(df_dict, remove_rows, keep_rows): for key, df in df_dict.items(): print(key) initial_count = len(df_dict[key]) # 提前提取当前循环对应的匹配规则 keep_pattern = keep_rows[key] remove_pattern = remove_rows[key] df_dict[key] = ( df # 文本统一转小写 .assign(Text=lambda x: x['Text'].str.lower()) # 保留提及目标人物的行,通过@引用外部变量 .query('Text.str.contains(@keep_pattern)') # 删除提及其他无关人物的行 .query('~Text.str.contains(@remove_pattern)') # 移除文本中所有URL .assign(Text=lambda x:x['Text'].apply(lambda s: re.sub(r'\w+:\/{2}[\d\w-]+(\.[\d\w-]+)*(?:(?:\/[^\s/]*))*', '', s))) ) final_count = len(df_dict[key]) print("%d tweets kept out of %d" % (final_count, initial_count)) return df_dict
内容的提问来源于stack exchange,提问作者Dian Basit
相关产品推荐
相关产品推荐

