如何在Pandas DataFrame中生成符合条件的规则列表列
问题描述
现有如下DataFrame:
id rule1 rule2 rule3 1 True True False 2 True True True 3 False False False 4 False True False 5 True False True ..
以及规则映射字典:
{'rule1': 'Rule one', 'rule2': 'Rule two', 'rule3': 'Rule three'}
需求是新增一列list_of_rules,该列存储DataFrame中值为True的列对应的字典规则名称列表,期望输出如下:
id rule1 rule2 rule3 list_of_rules 1 True True False ['Rule one', 'Rule two'] 2 True True True ['Rule one', 'Rule two', 'Rule three'] 3 False False False [''] 4 False True False ['Rule two'] 5 True False True ['Rule one', 'Rule three'] ..
当前使用的解决方案代码如下:
df.loc[df['rule1'] == True, 'rule1'] = 'Rule one' df.loc[df['rule2'] == True, 'rule2'] = 'Rule two' df.loc[df['rule3'] == True, 'rule3'] = 'Rule three' df.loc[df['rule1'] == False, 'rule1'] = '' df.loc[df['rule2'] == False, 'rule2'] = '' df.loc[df['rule3'] == False, 'rule3'] = '' df['list_of_rules'] = df[['rule1', 'rule2', 'rule3']].apply("-".join, axis=1).str.strip('-').str.split('-')
但该方案会导致第5行的list_of_rules出现空元素(表现为双逗号),实际输出如下:
id rule1 rule2 rule3 list_of_rules 1 True True False ['Rule one', 'Rule two'] 2 True True True ['Rule one', 'Rule two', 'Rule three'] 3 False False False [''] 4 False True False ['Rule two'] 5 True False True ['Rule one', '', 'Rule three'] ..
需要修复这个问题,同时直接利用给定的规则字典实现需求。
解决方案
方法一:修复原有方案
原有方案的问题在于字符串拼接分割时会保留空元素,可直接遍历行元素过滤空值,同时处理全空的边界情况:
rule_map = {'rule1': 'Rule one', 'rule2': 'Rule two', 'rule3': 'Rule three'} # 批量替换规则列的布尔值为对应名称或空字符串 for col in rule_map: df[col] = df[col].map({True: rule_map[col], False: ''}) # 生成目标列:直接过滤行中的空元素,全空时返回[''] df['list_of_rules'] = df[list(rule_map.keys())].apply( lambda x: [item for item in x if item] or [''], axis=1 )
方法二:直接利用字典筛选(推荐)
无需修改原DataFrame的规则列,直接通过布尔值匹配对应的规则名称,逻辑更清晰高效:
rule_map = {'rule1': 'Rule one', 'rule2': 'Rule two', 'rule3': 'Rule three'} def get_matching_rules(row): # 筛选当前行值为True的规则列,映射为对应名称 matched = [rule_map[col] for col in rule_map if row[col]] # 无匹配时返回[''],否则返回匹配列表 return matched if matched else [''] df['list_of_rules'] = df.apply(get_matching_rules, axis=1)
该方法避免了对原数据列的修改,代码可读性和维护性更强,也不会出现空元素的问题。
内容的提问来源于stack exchange,提问作者Matas M
相关产品推荐
相关产品推荐

