如何正确判断Pandas DataFrame中替换文件的编号是否匹配?
Pandas DataFrame 替换文件编号校验实现方法
需求说明
现有包含file、comment、number三列的大型Pandas DataFrame,其中部分行的comment以Replacing: 开头,表示该行是指定原文件的替代版本,要求替代文件的number必须与原文件一致。需要生成校验结果列(或列表),标记每行是否符合规则,示例期望结果为['True', 'True', 'False', 'False', 'True', 'True']。
实现方案
方法一:高效向量化处理(适合大型DataFrame)
import pandas as pd # 初始化测试数据 df_test = pd.DataFrame(data=None, columns=['file','comment','number']) df_test.file = ['file_1', 'file_1_v2', 'file_2', 'file_2_v2', 'file_3', 'file_3_v2'] df_test.comment = ['none', 'Replacing: file_1', 'none', 'Replacing: file_2', 'none', 'Replacing: file_3'] df_test.number = ['12', '12', '15', '16', '18', '18'] # 1. 从comment中提取被替换的原文件名 df_test['original_file'] = df_test['comment'].str.extract(r'Replacing: (.*)') # 2. 构建原文件到对应编号的映射字典 original_number_map = df_test.loc[df_test['comment'] == 'none', ['file', 'number']].set_index('file')['number'] # 3. 计算替换行的校验结果 df_test['check_result'] = df_test.apply( lambda row: row['number'] == original_number_map.get(row['original_file']) if pd.notna(row['original_file']) else None, axis=1 ) # 4. 为非替换行匹配对应替换行的校验结果 replacement_check_map = df_test.dropna(subset=['original_file']).set_index('original_file')['check_result'] df_test.loc[df_test['comment'] == 'none', 'check_result'] = df_test.loc[df_test['comment'] == 'none', 'file'].map(replacement_check_map) # 转换为字符串类型(匹配期望输出格式) df_test['check_result_str'] = df_test['check_result'].astype(str) # 输出结果列表 print(df_test['check_result_str'].tolist()) # 输出:['True', 'True', 'False', 'False', 'True', 'True']
方法二:分步逻辑实现(易理解)
import pandas as pd df_test = pd.DataFrame(data=None, columns=['file','comment','number']) df_test.file = ['file_1', 'file_1_v2', 'file_2', 'file_2_v2', 'file_3', 'file_3_v2'] df_test.comment = ['none', 'Replacing: file_1', 'none', 'Replacing: file_2', 'none', 'Replacing: file_3'] df_test.number = ['12', '12', '15', '16', '18', '18'] # 提取原文件名 df_test['original_file'] = df_test['comment'].str.extract(r'Replacing: (.*)') # 原文件编号映射 original_num_map = df_test[df_test['comment'] == 'none'].set_index('file')['number'].to_dict() # 定义校验函数 def validate_row(row): # 处理替换行 if pd.notna(row['original_file']): return row['number'] == original_num_map.get(row['original_file']) # 处理非替换行,匹配对应替换行的结果 replacement_file = f"{row['file']}_v2" replacement_row = df_test[df_test['file'] == replacement_file] return replacement_row['check_result'].values[0] if not replacement_row.empty else True # 先计算替换行结果 df_test['check_result'] = df_test.apply( lambda x: x['number'] == original_num_map.get(x['original_file']) if pd.notna(x['original_file']) else None, axis=1 ) # 填充非替换行结果 df_test['check_result'] = df_test.apply(validate_row, axis=1) # 转字符串格式 df_test['check_result_str'] = df_test['check_result'].astype(str) print(df_test['check_result_str'].tolist())
关键说明
- 正则
r'Replacing: (.*)'用于精准提取comment中的原文件名,若comment格式有变化需调整正则表达式 - 大型数据集优先使用方法一,通过向量化操作(
map、str方法)替代apply遍历,大幅提升处理效率 - 若替换文件命名规则不是
原文件名_v2,需调整非替换行匹配逻辑,建议通过original_file关联而非文件名构造
内容的提问来源于stack exchange,提问作者Marcus K.
相关产品推荐
相关产品推荐

