基于另一列更新DataFrame行数据:修正日期与名称列
优化DataFrame日期与名称列的批量处理
问题背景
原始DataFrame结构:
Date Name 0 07/08/2023 LUZZO GRACA 03/08/23 1 08/08/2023 SEPA PREDICA 2 08/08/2023 MINIPRECO FAMILY 05/08/23 3 09/08/2023 PQ. CASA DE MUS 08/08/23
需要完成两项操作:
- 将
Date列替换为Name列末尾的日期(若存在),并将两位年份补全为yyyy格式(前缀加"20") - 移除
Name列末尾的日期部分,保留名称主体
处理后的目标效果:
Date Name 0 03/08/2023 LUZZO GRACA 1 08/08/2023 SEPA PREDICA 2 05/08/2023 MINIPRECO FAMILY 3 08/08/2023 PQ. CASA DE MUS
原解法(低效)
最初通过两次apply迭代分别更新两列,需要遍历Name列两次,效率较低:
import re def update_date(row): last_part = row["Name"].rsplit(' ', 1)[-1] if re.match(r'(?:[0-2]\d|3[0-2])/(?:0[1-9]|1[0-2])/(?:[2-9]\d)', last_part): return last_part[:6]+"20"+last_part[6:] return row["Date"] def update_name(row): first_part, last_part = row["Name"].rsplit(' ', 1) if re.match(r'(?:[0-2]\d|3[0-2])/(?:0[1-9]|1[0-2])/(?:[2-9]\d)', last_part): return first_part.strip() return row["Name"] df["Date"] = df.apply(update_date, axis=1) df["Name"] = df.apply(update_name, axis=1)
优化方案:一次正则匹配完成双列更新
利用str.extract一次性从Name列提取名称主体和日期部分,仅需遍历一次即可完成两列更新:
import pandas as pd import re # 定义正则:匹配名称主体 + 可选的末尾日期(dd/mm/yy格式) pattern = r'^(.*?)\s*((?:[0-2]\d|3[0-1])/(?:0[1-9]|1[0-2])/[2-9]\d)?$' # 一次性提取分组结果 extracted = df['Name'].str.extract(pattern) extracted.columns = ['clean_name', 'extracted_date'] # 更新Name列:用提取的名称主体,无日期则保留原内容 df['Name'] = extracted['clean_name'].fillna(df['Name']).str.strip() # 更新Date列:提取到日期则补全年份,否则保留原日期 df['Date'] = extracted['extracted_date'].apply( lambda x: f"{x[:6]}20{x[6:]}" if pd.notna(x) else df['Date'] )
关键说明
- 正则表达式
^(.*?)\s*((?:[0-2]\d|3[0-1])/(?:0[1-9]|1[0-2])/[2-9]\d)?$:(.*?):非贪婪匹配名称主体,避免误吞日期前的空格\s*:匹配名称与日期之间的任意空白字符- 日期匹配规则:限制为有效日期范围(01-31日,01-12月),确保匹配准确性
?:标记日期部分为可选,兼容无日期的行
- 仅需一次遍历处理
Name列,相比两次apply大幅提升处理效率
内容的提问来源于stack exchange,提问作者e1k
相关产品推荐
相关产品推荐

