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

pandas apply获取字典值报Series不可哈希错误的解决方法

问题说明

需要从存储域名对计数的字典中查询匹配值,为pandas DataFrame生成新列。
使用的计数字典结构如下:

pair_devices_count = 
{('tWAAAA.jg', 'ttNggB.jg'): 1,
('tWAAAM.jg', 'ttWVsM.jg'): 2,
('tWAAAN.CV', 'ttNggB.AS'): 1,
 ('tWAAAN.CV', 'ttNggB.CV'): 2,
 ('tWAAAN.CV', 'ttNggB.QG'): 1}

原写法触发Series不可哈希报错的核心原因:DataFrame的apply方法默认按列遍历(axis=0),传入lambda函数的参数是整列的Series对象,而可变类型的Series无法作为字典的键完成哈希查询。
原错误代码:

train_data[['domain', 'target_domain']].apply(lambda x: pair_devices_count.get((x), 0))
可行实现方案

以下三种方案都可以实现需求,按性能从高到低排序:

  • 方案1:向量化匹配(大数据量首选)
    将原字典转换为多级索引的Series,通过pandas原生的关联匹配逻辑完成赋值,无逐行循环开销,速度最快:
    import pandas as pd
    
    # 转换字典为带多级域名索引的计数Series
    ref_s = pd.Series(pair_devices_count, name="pair_devices_count")
    # 关联匹配到原表,缺失值填充0
    train_data = train_data.join(
        ref_s, 
        on=["domain", "target_domain"]
    ).fillna({"pair_devices_count": 0})
    
  • 方案2:列表推导式(写法简洁,性能够用)
    直接zip两列的值逐对拼元组查字典,写法简单,性能远好于逐行apply,适合中小数据量:
    train_data["pair_devices_count"] = [
        pair_devices_count.get((dom, tgt_dom), 0)
        for dom, tgt_dom in zip(train_data["domain"], train_data["target_domain"])
    ]
    
  • 方案3:逐行apply(逻辑直观,适合小数据量)
    给apply添加axis=1参数改为按行遍历,此时传入lambda的是单行数据,提取两个字段拼元组查询即可:
    train_data["pair_devices_count"] = train_data[["domain", "target_domain"]].apply(
        lambda row: pair_devices_count.get((row["domain"], row["target_domain"]), 0),
        axis=1
    )
    

内容的提问来源于stack exchange,提问作者MONEY LONGER

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 08:54:22