基于车型与工单匹配的DataFrame字符串匹配及日期填充求助
问题与解决方案
问题背景
我有两个来自经销商维修车间的多车型维护工单DataFrame:
firstworkitems:整合所有车型的首次维护计划lastworkitems:整合所有车型的末次维护计划,其Title字段包含合同变更(rccs)的附加文本
需求:在**相同车型(Car Model)和工单(Work Item)**的前提下,检查lastworkitems的Title是否包含firstworkitems对应的Title字符串,然后在lastworkitems中新增First Start Date和First Finish Date两列,填入firstworkitems对应的日期值。
原循环代码无法正常运行,代码如下:
for x in range(len(lastworkitems)): for y in range(len(firstworkitems)): if lastworkitems.loc[x, 'Car Model'] == firstworkitems.loc[y, 'Car Model']: if lastworkitems.loc[x, 'Work Item'] == firstworkitems.loc[y, 'Work Item']: lastworkitems.loc[x, 'First Start Date'] = np.where(lastworkitems.loc[x, 'Title'].str.contains(firstworkitems.loc[y, 'Title']), firstworkitems.loc[y, 'Start Date'], 0) lastworkitems.loc[x, 'First Finish Date'] = np.where(lastworkitems.loc[x, 'Title'].str.contains(firstworkitems.loc[y, 'Title']), firstworkitems.loc[y, 'Finish Date'], 0)
原代码问题分析
- 双重循环效率低下:嵌套循环会随着DataFrame行数增加急剧变慢,违背pandas的向量化设计原则。
- 赋值逻辑错误:每次匹配到相同车型和工单时,会覆盖之前的赋值结果,最终可能只保留最后一次匹配的记录,而非正确对应项。
- 字符串判断错误:单个字符串对象没有
str属性,直接调用lastworkitems.loc[x, 'Title'].str.contains会触发AttributeError,应该用Python原生的in关键字判断子串。
解决方案
方案一:优化循环实现(适合小数据集)
先通过车型+工单分组建立映射,减少循环次数,修正赋值逻辑:
import pandas as pd import numpy as np # 初始化新增列 lastworkitems['First Start Date'] = np.nan lastworkitems['First Finish Date'] = np.nan # 构建(车型, 工单)到首次计划行的映射 first_mapping = firstworkitems.set_index(['Car Model', 'Work Item']) # 遍历末次计划的每一行 for idx, row in lastworkitems.iterrows(): key = (row['Car Model'], row['Work Item']) if key in first_mapping.index: first_row = first_mapping.loc[key] # 判断末次Title是否包含首次Title if first_row['Title'] in row['Title']: lastworkitems.loc[idx, 'First Start Date'] = first_row['Start Date'] lastworkitems.loc[idx, 'First Finish Date'] = first_row['Finish Date']
方案二:pandas向量化实现(推荐,适合大数据集)
利用merge关联数据,再过滤符合条件的记录,最后合并回原DataFrame:
# 基于车型和工单合并两个数据集,区分后缀 merged_df = pd.merge( lastworkitems, firstworkitems, on=['Car Model', 'Work Item'], suffixes=('_last', '_first') ) # 筛选出末次Title包含首次Title的记录 valid_matches = merged_df[merged_df['Title_last'].str.contains(merged_df['Title_first'])] # 提取需要的日期列,合并回末次计划数据集 lastworkitems = lastworkitems.merge( valid_matches[['Car Model', 'Work Item', 'Start Date', 'Finish Date']], on=['Car Model', 'Work Item'], how='left' ).rename(columns={ 'Start Date': 'First Start Date', 'Finish Date': 'First Finish Date' })
内容的提问来源于stack exchange,提问作者Jennerz
相关产品推荐
相关产品推荐

