如何拆分pandas DataFrame中格式为‘Nov 4, 1992 (27)’的DoB列生成日期与年龄?
优雅处理Pandas中出生日期与年龄计算的方案
嘿,我来帮你搞定这个问题!针对你手里格式为Nov 4, 1992 (27)的dob列,用正则表达式配合Pandas的日期工具能写出简洁优雅的代码,而且用当前日期计算年龄比直接提取括号里的静态数字更准确(毕竟抓取的年龄是当时的,现在用可能已经过期啦)。
步骤1:提取并转换出生日期为dd/mm/yyyy格式
我们可以用正则表达式快速剥离括号里的年龄部分,只保留日期字符串,再用pd.to_datetime()完成转换:
import pandas as pd # 假设你的DataFrame名为df # 1. 提取括号前的日期部分(正则匹配开头到左括号前的内容) df['dob_date_str'] = df['dob'].str.extract(r'^(.*?)\s+\(')[0] # 2. 转换为datetime类型,再格式化为dd/mm/yyyy的字符串 df['date_of_birth'] = pd.to_datetime(df['dob_date_str']).dt.strftime('%d/%m/%Y')
如果你需要保留datetime对象方便后续计算(比如年龄),可以跳过strftime,直接保留转换结果:
df['dob_datetime'] = pd.to_datetime(df['dob_date_str'])
步骤2:基于当前日期计算真实年龄
不用拆分字符串提取括号里的数字,我们可以通过出生日期和当前日期的差值,计算出精确的当前年龄(考虑生日是否已过的情况):
from datetime import datetime current_date = datetime.now() # 先计算年份差 df['age'] = current_date.year - df['dob_datetime'].dt.year # 调整:如果今年生日还没到,年龄减1 birthday_not_passed_mask = (df['dob_datetime'].dt.month > current_date.month) | \ ((df['dob_datetime'].dt.month == current_date.month) & (df['dob_datetime'].dt.day > current_date.day)) df.loc[birthday_not_passed_mask, 'age'] -= 1
也可以用Pandas的Timestamp替代datetime,写法更统一:
current_date = pd.Timestamp.now() df['age'] = current_date.year - df['dob_datetime'].dt.year birthday_not_passed_mask = (df['dob_datetime'].dt.month > current_date.month) | \ ((df['dob_datetime'].dt.month == current_date.month) & (df['dob_datetime'].dt.day > current_date.day)) df.loc[birthday_not_passed_mask, 'age'] -= 1
可选:提取原字符串中的静态年龄(用于对比)
如果你想保留抓取时的年龄作为参考,也可以用正则快速提取:
df['extracted_age'] = df['dob'].str.extract(r'\((\d+)\)')[0].astype(int)
整合一步到位的写法
可以把提取和转换合并,减少中间列:
import pandas as pd from datetime import datetime # 处理日期 df['dob_datetime'] = pd.to_datetime(df['dob'].str.extract(r'^(.*?)\s+\(')[0]) df['date_of_birth'] = df['dob_datetime'].dt.strftime('%d/%m/%Y') # 计算年龄 current_date = datetime.now() df['age'] = current_date.year - df['dob_datetime'].dt.year mask = (df['dob_datetime'].dt.month > current_date.month) | \ ((df['dob_datetime'].dt.month == current_date.month) & (df['dob_datetime'].dt.day > current_date.day)) df.loc[mask, 'age'] -= 1
这样处理后,你既得到了标准格式的出生日期,又有了实时准确的年龄,代码也比手动拆分字符串简洁很多~
内容的提问来源于stack exchange,提问作者Edd Webster
相关产品推荐
相关产品推荐

