Pandas多正则模式提取并保留NaN值规整结果的实现问题
规整Pandas日期字符串提取结果为年份/日期/月份列
原始数据
首先定义目标DataFrame:
import pandas as pd df = pd.DataFrame({'date' : ['Nov 21, 2000','Sep 08, 2000','Nov, 1999','Nov 26, 1998','Apr, 2002','2001','Mar 26, 1998', 'Oct 07, 1999', 'Nov 20, 1995', 'Mar 15, 1996']})
原始数据展示:
| date | |
|---|---|
| 0 | Nov 21, 2000 |
| 1 | Sep 08, 2000 |
| 2 | Nov, 1999 |
| 3 | Nov 26, 1998 |
| 4 | Apr, 2002 |
| 5 | 2001 |
| 6 | Mar 26, 1998 |
| 7 | Oct 07, 1999 |
| 8 | Nov 20, 1995 |
| 9 | Mar 15, 1996 |
原方法问题
使用正则'(\\d{4})|\\s(\\d{2}),|([aA-zZ]+)'配合extractall时,会将每行拆分为多个match行,且结果中存在大量NaN,无法直接得到每行对应年份、日期、月份的规整结构。
解决方案
方法1:一次性匹配提取(推荐)
编写覆盖所有日期格式的正则表达式,用str.extract一次性提取三个字段:
# 正则匹配三种日期模式:完整日期、月+年、仅年 pattern = r'(?:([A-Za-z]+)\s)?(?:(\d{2}),\s)?(\d{4})' # 提取数据 result = df['date'].str.extract(pattern) # 调整列顺序为年份、日期、月份,并重命名列 result = result[[2, 1, 0]].rename(columns={2:'year', 1:'day', 0:'month'}) print(result)
输出结果:
| year | day | month | |
|---|---|---|---|
| 0 | 2000 | 21 | Nov |
| 1 | 2000 | 08 | Sep |
| 2 | 1999 | NaN | Nov |
| 3 | 1998 | 26 | Nov |
| 4 | 2002 | NaN | Apr |
| 5 | 2001 | NaN | NaN |
| 6 | 1998 | 26 | Mar |
| 7 | 1999 | 07 | Oct |
| 8 | 1995 | 20 | Nov |
| 9 | 1996 | 15 | Mar |
方法2:基于原extractall结果整理
如果必须基于之前的extractall结果处理,可通过分组聚合提取非NaN值:
p = '(\\d{4})|\\s(\\d{2}),|([aA-zZ]+)' extracted = df['date'].str.extractall(p) # 按原始行分组,提取每组内各列的第一个非NaN值 result = extracted.groupby(level=0).agg(lambda x: x.dropna().iloc[0] if not x.dropna().empty else pd.NA) # 调整列顺序为年份、日期、月份 result = result[[0, 1, 2]].rename(columns={0:'year', 1:'day', 2:'month'}) print(result)
该方法同样能得到规整结果,但效率低于方法1。
内容的提问来源于stack exchange,提问作者Himanshu Poddar
相关产品推荐
相关产品推荐

