You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 18:27:42