Pandas如何动态匹配DataFrame与字典键值对并修改对应列值
Pandas动态字典规则批量修改DataFrame实现
场景说明
你当前持有的测试DataFrame结构如下:
import pandas as pd df = pd.DataFrame({ "colA": [1, 1, 2, 2, 2, 3, 4], "colB": ["1a", "1b", "2a", "2b", "2c", "3a", "4a"], "colC": ["Yes"] * 7, "colD": ["Yes"] * 7 })
用于配置过滤规则的字典格式如下:
filterDict = { "1": ["1a", "1b"], "2": ["2a", "2b"] }
需要实现的逻辑:
- 逐行判断:若行的
colA列值存在于字典键中,且同一行colB列值属于该键对应的列表值,就将该行colC、colD列值修改为No - 逻辑需动态适配字典配置,新增/修改过滤规则时无需改动判断代码,替代原有的硬编码写法
原硬编码写法存在明显局限,每新增一组过滤规则就要手动追加判断条件,维护成本高:
# 原硬编码写法(不推荐) mask = ((df["colA"] == "1") & (df["colB"].isin(["1a","1b"])) | ((df["colA"] == "2") & (df["colB"].isin(["2a","2b"]))) df.loc[mask,["colC","colD"]] = ["No","No"]
推荐实现方案(向量化写法,性能最优)
核心思路是初始化全False的布尔掩码,遍历字典配置动态累加匹配条件,最终批量修改符合条件的行,全程使用pandas原生向量化运算,性能远高于逐行循环。
# 初始化掩码,默认所有行都不匹配 mask = pd.Series(False, index=df.index) for colA_key, colB_valid_list in filterDict.items(): # 类型兼容处理:示例中字典键为字符串,df中colA为整数,自动做类型转换避免匹配失败 # 如果你的场景中colA本身就是字符串类型,可删除下面4行类型转换代码 try: colA_key = int(colA_key) except ValueError: pass # 生成当前键值对对应的匹配条件,累加到总掩码中 current_match = (df["colA"] == colA_key) & (df["colB"].isin(colB_valid_list)) mask = mask | current_match # 批量修改符合条件的行 df.loc[mask, ["colC", "colD"]] = "No"
运行结果
执行上述代码后得到的DataFrame完全符合预期:
colA colB colC colD 0 1 1a No No 1 1 1b No No 2 2 2a No No 3 2 2b No No 4 2 2c Yes Yes 5 3 3a Yes Yes 6 4 4a Yes Yes
扩展说明
后续如果需要新增过滤规则,只需要修改filterDict即可,比如新增规则colA=3且colB为3a时改为No,只需要在字典中追加键值对"3": ["3a"],无需改动任何逻辑代码。
内容的提问来源于stack exchange,提问作者redrobinyum
相关产品推荐
相关产品推荐

