Pandas多列条件统计问题:如何精准匹配指定名称并计数?
解决Pandas DataFrame中精准匹配分组名称并统计符合条件行数的问题
需求与问题背景
需要统计Pandas DataFrame中同时满足以下两个条件的行数:
result列包含PASSgroup列精准匹配指定名称(如test_abc、test)
用户测试代码及数据如下:
import pandas as pd # Sample data data = { "group": [ "/path/to/file/test_abc_n2_manipulation.txt", "/path/to/file/test_n2_manipulation.txt", "/path/to/file/test_k2_manipulation.txt", "/path/to/other/test_abc_a5_manipulation.txt", "/path/to/file/some_text.txt", "/path/to/file/test_abc_hello.txt" ], "result": [ "PASS", "PASS", "FAIL", "FAIL", "PASS", "PASS" ] } df = pd.DataFrame(data) name = "test_abc" name2 = "test" results_match = df.result.str.contains('PASS') & df.group.str.contains(fr'\b{name}\b', regex=True) results_match_2 = df.result.str.contains('PASS') & df.group.str.contains(fr'\b{name2}\b', regex=True) print(results_match) print(results_match_2)
问题现象
使用正则单词边界\b匹配时,预期results_match返回2个匹配、results_match_2返回1个匹配,但实际输出全为False:results_match实际输出:
0 False 1 False 2 False 3 False 4 False 5 False dtype: bool
results_match_2实际输出:
0 False 1 False 2 False 3 False 4 False 5 False dtype: bool
问题原因
正则中的\b是单词边界,仅匹配\w(字母、数字、下划线)与非\w字符的边界。而目标名称(如test_abc)中的下划线属于\w范畴,当名称前后是下划线或字母时,\b无法识别为边界,导致匹配失败。比如test_abc_n2中,test_abc后面的下划线和字母n都属于\w,没有边界,所以\btest_abc\b无法匹配。
解决方法
方法1:自定义边界正则匹配
修改正则表达式,匹配目标名称前后为路径分隔符/、下划线_或字符串首尾,确保目标名称是独立的组件:
import pandas as pd data = { "group": [ "/path/to/file/test_abc_n2_manipulation.txt", "/path/to/file/test_n2_manipulation.txt", "/path/to/file/test_k2_manipulation.txt", "/path/to/other/test_abc_a5_manipulation.txt", "/path/to/file/some_text.txt", "/path/to/file/test_abc_hello.txt" ], "result": [ "PASS", "PASS", "FAIL", "FAIL", "PASS", "PASS" ] } df = pd.DataFrame(data) name = "test_abc" name2 = "test" # 自定义边界:匹配目标名称前后是/、_或字符串首尾 results_match = df.result.str.contains('PASS') & df.group.str.contains(fr'(?:^|/|_){name}(?:_|/|$)', regex=True) results_match_2 = df.result.str.contains('PASS') & df.group.str.contains(fr'(?:^|/|_){name2}(?:_|/|$)', regex=True) print("results_match匹配行数:", results_match.sum()) print(results_match) print("\nresults_match_2匹配行数:", results_match_2.sum()) print(results_match_2)
正则说明
(?:^|/|_):非捕获组,匹配字符串开头、路径分隔符/或下划线_{name}:要匹配的目标名称(?:_|/|$):非捕获组,匹配下划线_、路径分隔符/或字符串结尾
运行后可得到预期结果:results_match匹配2行,results_match_2匹配1行。
方法2:提取文件名组件后匹配
先从路径中提取文件名,按下划线分割为组件列表,再检查目标名称是否在组件中,同时结合result列的条件:
import pandas as pd data = { "group": [ "/path/to/file/test_abc_n2_manipulation.txt", "/path/to/file/test_n2_manipulation.txt", "/path/to/file/test_k2_manipulation.txt", "/path/to/other/test_abc_a5_manipulation.txt", "/path/to/file/some_text.txt", "/path/to/file/test_abc_hello.txt" ], "result": [ "PASS", "PASS", "FAIL", "FAIL", "PASS", "PASS" ] } df = pd.DataFrame(data) name = "test_abc" name2 = "test" # 提取文件名并分割为下划线分隔的组件 df['group_components'] = df['group'].str.split('/').str[-1].str.split('_') # 筛选符合条件的行 results_match = df[(df['result'] == 'PASS') & (df['group_components'].apply(lambda x: name in x))] results_match_2 = df[(df['result'] == 'PASS') & (df['group_components'].apply(lambda x: name2 in x))] print("results_match匹配行数:", len(results_match)) print("results_match_2匹配行数:", len(results_match_2))
这个方法逻辑更直观,适合处理复杂的文件名结构,同样能得到正确的统计结果。
内容的提问来源于stack exchange,提问作者user3421370
相关产品推荐
相关产品推荐

