需求:使用Pandas或Regex提取序列索引不匹配行的Python方案
问题描述
我有如下Pandas DataFrame:
| ref_nbr | Date | extracted_seq | correct_seq |
|---|---|---|---|
| FGR0 | 2022-05-02 16:24 | '0312' | '0123' |
| FGR3 | 2022-05-02 16:29 | '0312' | '0123' |
| FGR1 | 2022-05-02 16:32 | '0312' | '0123' |
| FGR2 | 2022-05-02 16:36 | '0312' | '0123' |
需要提取extracted_seq与correct_seq对应索引位置存在字符不匹配的行,预期输出为第二行:
| ref_nbr | Date | extracted_seq | correct_seq |
|---|---|---|---|
| FGR3 | 2022-05-02 16:29 | '0312' | '0123' |
以下是基于Pandas和正则的实现方案:
方案一:Pandas逐字符对比
注意:示例中所有行的extracted_seq和correct_seq值完全一致,若按"存在至少一个不匹配位置"筛选,所有行都会被选中。结合预期输出推测需求应为筛选两个序列所有对应位置字符都不匹配的行(推测示例中第二行的extracted_seq实际应为'3210'这类完全不匹配的值),代码如下:
import pandas as pd # 构造示例DataFrame(修正第二行extracted_seq以符合预期输出逻辑) df = pd.DataFrame({ 'ref_nbr': ['FGR0', 'FGR3', 'FGR1', 'FGR2'], 'Date': ['2022-05-02 16:24', '2022-05-02 16:29', '2022-05-02 16:32', '2022-05-02 16:36'], 'extracted_seq': ["'0312'", "'3210'", "'0312'", "'0312'"], 'correct_seq': ["'0123'", "'0123'", "'0123'", "'0123'"] }) # 定义函数:检查两个序列所有对应位置字符都不匹配 def all_positions_mismatch(extracted, correct): # 去除字符串两端的单引号 e_str = extracted.strip("'") c_str = correct.strip("'") # 长度不一致直接判定为不匹配(可选逻辑) if len(e_str) != len(c_str): return False # 逐字符对比,所有位置都不匹配返回True return all(e != c for e, c in zip(e_str, c_str)) # 筛选符合条件的行 result_df = df[df.apply(lambda row: all_positions_mismatch(row['extracted_seq'], row['correct_seq']), axis=1)] print(result_df)
如果需求是只要存在任意一个位置不匹配就提取,只需修改函数为:
def any_position_mismatch(extracted, correct): e_str = extracted.strip("'") c_str = correct.strip("'") if len(e_str) != len(c_str): return True return any(e != c for e, c in zip(e_str, c_str)) result_df = df[df.apply(lambda row: any_position_mismatch(row['extracted_seq'], row['correct_seq']), axis=1)]
方案二:正则表达式匹配
针对固定长度的序列(比如示例中的4位),可以用正则直接匹配所有位置都不匹配的情况。以correct_seq为'0123'为例,构造正则匹配被单引号包裹、每个位置都与目标字符不同的字符串:
import pandas as pd # 构造示例DataFrame df = pd.DataFrame({ 'ref_nbr': ['FGR0', 'FGR3', 'FGR1', 'FGR2'], 'Date': ['2022-05-02 16:24', '2022-05-02 16:29', '2022-05-02 16:32', '2022-05-02 16:36'], 'extracted_seq': ["'0312'", "'3210'", "'0312'", "'0312'"], 'correct_seq': ["'0123'", "'0123'", "'0123'", "'0123'"] }) # 正则规则:第一位非0,第二位非1,第三位非2,第四位非3,且被单引号包裹 mismatch_pattern = r"'[^0][^1][^2][^3]'" # 筛选符合正则的行 result_df = df[df['extracted_seq'].str.match(mismatch_pattern)] print(result_df)
内容的提问来源于stack exchange,提问作者Tarak Pandya
相关产品推荐
相关产品推荐

