如何从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

图案部分

(?&lt;!\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\19982/06/1998),但获得更强大的解决方案的代价非常小。

【讨论】:

提取 4 位数字的正则表达式解决方案适用于 99% 日期(不是日期时间)格式 @OlvinR​​oght 我的解决方案可以 100% 工作(只要格式是标准的而不是完全任意的)并且“未经测试”的代码要少得多 这就是您编辑帖子中的源数据以使其“100% 工作”的原因? :D :D :D @OlvinR​​oght 是的,让我们比较一个需要您调用 str.replace 来更改斜线方向的解决方案但支持所有标准日期和日期时间格式,与一个解决方案正在使用一个正则表达式,如果它得到一个意外的格式(即使它是标准的)就会中断 能否提供正则表达式\d4 会中断而pandas 不会中断的日期格式?

以上是关于如何从python中不同类型的日期中提取年份的主要内容,如果未能解决你的问题,请参考以下文章

从列中提取日期并在 R 中缺少年份时添加年份

python pandas 从日期时间中提取年份:df['year'] = df['date'].year 不起作用

如何从日期字符串中提取年份?

如何从两个不同的日期获得年份差异?

如何从熊猫数据框中提取日期/年份/月份?

如何从 MDX 查询中提取日期中的月份年份