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

Python中如何将DataFrame每行与字典列表匹配并添加标记列?

解决方案:DataFrame与规则字典列表的匹配实现

问题原因分析

你遇到的TypeError: unhashable type: 'dict'错误,是因为尝试将不可哈希的字典对象作为匹配的键使用(比如把整行字典直接拿去做哈希查找)。字典属于可变类型,无法被哈希,因此会触发这个错误。

两种可行实现思路

思路1:直接用Pandas逐行处理(推荐)

无需转换DataFrame格式,直接利用apply逐行遍历,结合自定义匹配函数完成规则校验,逻辑更灵活,能应对部分列匹配、集合交集匹配等复杂场景。

步骤与代码示例

  1. 定义规则列表(可根据实际需求调整结构):
import pandas as pd

# 示例规则列表:每个规则包含匹配条件和描述
rules_list = [
    {"condition": {"code1": ("VA", "HC"), "code4": float("nan")}, "desc": "rules1"},
    {"condition": {"code2": ("103", "104"), "code4": "computerscience"}, "desc": "rules2"},
    {"condition": {"code6": ("594",)}, "desc": "rules12"},
    # 补充其他规则...
]
  1. 编写匹配函数:
def match_single_row(row, rules):
    """检查单行数据是否匹配任意规则,返回匹配状态和规则描述"""
    for rule in rules:
        match_flag = True
        for col, expected_val in rule["condition"].items():
            # 处理空值(nan)的匹配逻辑
            if pd.isna(row[col]):
                if not pd.isna(expected_val):
                    match_flag = False
                    break
            else:
                # 处理集合/元组类型的匹配(示例为交集匹配,可改为完全匹配)
                if isinstance(expected_val, (tuple, list, set)):
                    if not set(row[col]) & set(expected_val):
                        match_flag = False
                        break
                # 处理单一值的匹配
                else:
                    if row[col] != expected_val:
                        match_flag = False
                        break
        if match_flag:
            return (True, rule["desc"])
    # 无匹配规则时返回默认值
    return (False, "None")
  1. 应用到DataFrame:
# 假设df是你的原始数据DataFrame
df[["isHit", "rules_desc"]] = df.apply(
    lambda row: match_single_row(row, rules_list),
    axis=1,
    result_type="expand"
)

思路2:转换为字典列表后处理(适合完全匹配场景)

如果必须转换为字典列表,需要先将行数据和规则条件转换为可哈希的结构(比如元组、frozenset),避免字典不可哈希的问题。这种方式仅适合全列完全匹配的场景。

步骤与代码示例

  1. 定义哈希转换函数:
def to_hashable(item):
    """将不可哈希的对象转换为可哈希类型"""
    if pd.isna(item):
        return None
    elif isinstance(item, (tuple, list)):
        return frozenset(item)
    else:
        return item

def row_to_hashable(row_dict):
    """将整行字典转换为可哈希的元组"""
    return tuple(sorted((k, to_hashable(v)) for k, v in row_dict.items()))
  1. 构建规则哈希映射:
rules_map = {}
for rule in rules_list:
    # 将规则条件转换为可哈希结构
    hashable_condition = row_to_hashable(rule["condition"])
    rules_map[hashable_condition] = (True, rule["desc"])
  1. 处理字典列表并匹配:
# 将DataFrame转为字典列表
row_dicts = df.to_dict("records")
# 逐行匹配
results = []
for row in row_dicts:
    hashable_row = row_to_hashable(row)
    results.append(rules_map.get(hashable_row, (False, "None")))
# 将结果合并回DataFrame
df[["isHit", "rules_desc"]] = results

方案选择建议

  • 若需处理部分列匹配、集合交集/包含匹配等复杂逻辑,优先使用思路1(Pandas直接处理),代码可读性和灵活性更强。
  • 若仅需全列完全匹配,可使用思路2,性能略优(但差异不大)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 08:25:20