如何从python中不同类型的日期中提取年份
Posted
技术标签:
【中文标题】如何从python中不同类型的日期中提取年份【英文标题】:how to extract year from different types of date in python 【发布时间】:2019-12-31 14:03:12 【问题描述】:我有一列包含不同类型的日期,例如:
2\06\1998
21.11.1998
18-02-2001
03/05/1999
20 july 1999
我只想要年份。
我尝试了不同类型的正则表达式,例如:
def get_date(date):
number= re.findall('\[0-9]\-0,1\\0,1\/0,1\[0-9]\-0,1\\0,1\/0,1\[0-9]', date)
return number[6:]
但我无法提取年份。 这种情况下最合适的正则表达式是什么? 做两种类型的正则表达式不是问题,一种用于格式 dd/mm/yyyy,另一种用于带有月份字母的日期。
【问题讨论】:
col.str[-4:]
?
尝试找到一个有 4 位数字的零件,例如:re.findall(r'\d4', date)
df.col_name.str[-4:]
@MarkWang 输入'2019/08/27'
@Anup 见上文
【参考方案1】:
您可以使用 2 个捕获组,在第一个组中,您可以使用反向引用 \1
捕获分隔符以匹配第二个的一致分隔符。
年份部分被捕获在第二组中。
^\d+([\\/. -])(?:\d+|[a-z]+)\1(\d4)$
Regex demo
除了使用锚点^
和$
,您还可以使用lookarounds
(?<!\S)\d+([\\/. -])(?:\d+|[a-z]+)\1(\d4)(?!\S)
Regex demo
图案部分
(?<!\S)
断言左边不是非空白字符
\d+
匹配 1+ 个数字
([\\/. -])
捕获组 1,匹配任何列出的
(?:
非捕获组
\d+
匹配1+位数
|
或
[a-z]+
匹配 1+ 个小写字符
)
关闭非捕获组
\1
反向引用第 1 组中捕获的内容
(\d4)
捕获组2,匹配4位年份
(?!\S)
断言右边的不是非空白字符
【讨论】:
【参考方案2】:我会使用简单的\d4
正则表达式。
import re
s = """2\\06\\1998
21.11.1998
18-02-2001
03/05/1999
20 july 1999"""
for date in s.splitlines():
year = re.search(r"\d4", date).group(0)
print(year)
【讨论】:
【参考方案3】:Pandas to_datetime 非常擅长识别不同的日期格式。唯一的问题是反斜杠,但如果你可以使用字符串格式替换它们,那么我认为它比使用正则表达式更容易。
import pandas as pd
df = pd.DataFrame("date": ["2\\06\\1998", "21.11.1998", "18-02-2001", "03/05/1999", "20 july 1999"])
df["date"] = df["date"].str.replace("\\", "/")
df["date"] = pd.to_datetime(df["date"])
df["date"].dt.year
0 1998
1 1998
2 2001
3 1999
4 1999
Name: date, dtype: int64
【讨论】:
【参考方案4】:不要落入正则表达式/'strip the last 4 characters' rabbit-hole。
如果到达另一种格式的日期(例如2019-08-27
),任何天真的正则表达式/剥离解决方案都会中断。
使用pd.to_datetime
让pandas 处理解析,然后直接抓取dt.year
。
df = pd.DataFrame('a': ['2/06/1998', '21.11.1998', '18-02-2001', '03/05/1999',
'20 july 1999', '2019-08-27'])
df['a'] = pd.to_datetime(df['a'])
print(df['a'].dt.year)
输出
0 1998
1 1998
2 2001
3 1999
4 1999
5 2019
注意:请注意,我必须更改斜线的方向(2\06\1998
到 2/06/1998
),但获得更强大的解决方案的代价非常小。
【讨论】:
提取 4 位数字的正则表达式解决方案适用于 99% 日期(不是日期时间)格式 @OlvinRoght 我的解决方案可以 100% 工作(只要格式是标准的而不是完全任意的)并且“未经测试”的代码要少得多 这就是您编辑帖子中的源数据以使其“100% 工作”的原因? :D :D :D @OlvinRoght 是的,让我们比较一个需要您调用str.replace
来更改斜线方向的解决方案但支持所有标准日期和日期时间格式,与一个解决方案正在使用一个正则表达式,如果它得到一个意外的格式(即使它是标准的)就会中断
能否提供正则表达式\d4
会中断而pandas 不会中断的日期格式?以上是关于如何从python中不同类型的日期中提取年份的主要内容,如果未能解决你的问题,请参考以下文章