如何在Pandas DataFrame中精准匹配目标字符并求和对应行?
问题分析与解决方案
原代码失效的原因
- 子字符串匹配逻辑错误:原代码用
cls in target判断子字符串是否存在,而非精准匹配完整的EC编号。比如1.1.1.1会被误判为存在于1.1.1.15中,导致本不该匹配的行被纳入求和范围。 - 多目标值未正确拆分:目标列表里的
'4.2.1.12; 1.1.1.15; 3.2.1.1'是分号分隔的多个EC编号,原代码没有拆分这些值,直接把整个字符串作为匹配依据,逻辑完全错误。
正确的精准匹配求和实现
核心思路:把每个目标字符串拆成精准的EC编号集合,再将DataFrame每行的Ko_EC拆成EC集合,判断两个集合是否有交集(即该行是否包含目标中的任意一个EC编号),最后对符合条件的行求和。
代码实现:
import pandas as pd # 构建DataFrame(原代码不变) classes = [('1.1.1.1', 16.7, 1), ('1.1.1.15', 30, 7), ('4.2.1.128', 40.5, 9), ('4.2.1.12', 57, 10), ('3.2.1.1 1.1.1.1', 22, 4)] labels = ['Ko_EC','FPKM', 'count'] alls = pd.DataFrame.from_records(classes, columns=labels) target_list = ['1.1.1.1', '4.2.1.128', '4.2.1.12; 1.1.1.15; 3.2.1.1', '1.1.1.15'] result = [] for target_str in target_list: # 拆分目标字符串为精准EC编号集合(处理分号+空格的分隔符) target_ecs = set([ec.strip() for ec in target_str.split(';')]) # 生成匹配掩码:判断该行的EC集合与目标EC集合是否有交集 mask = alls['Ko_EC'].apply(lambda x: len(set(x.split(' ')) & target_ecs) > 0) # 对匹配行求和 sum_vals = alls.loc[mask, ['FPKM', 'count']].sum().to_dict() sum_vals['target'] = target_str result.append(sum_vals) # 整理结果DataFrame result_df = pd.DataFrame(result).set_index('target').rename(columns={'count': 'Count'}) print(result_df)
代码说明
- 拆分目标EC:用
split(';')拆分分号分隔的目标,再用strip()去掉多余空格,转成集合方便后续交集判断。 - 精准匹配掩码:把每行的
Ko_EC按空格拆成集合,和目标集合求交集,交集非空则说明该行符合条件,彻底避免子字符串匹配的错误。 - 结果整理:把每个目标的求和结果收集成字典,再转成DataFrame,格式清晰易读。
运行结果:
FPKM Count target 1.1.1.1 38.7 5 4.2.1.128 40.5 9 4.2.1.12; 1.1.1.15; 3.2.1.1 109.0 21 1.1.1.15 30.0 7
该结果完全符合精准匹配要求:
1.1.1.1匹配第0行和第4行,FPKM=16.7+22=38.7,count=1+4=54.2.1.128仅匹配第2行,结果正确- 第三个目标匹配第1、3、4行,FPKM=30+57+22=109,count=7+10+4=21
1.1.1.15仅匹配第1行,结果正确
内容的提问来源于stack exchange,提问作者yan wang
相关产品推荐
相关产品推荐

