问题描述
我正在尝试从作为熊猫系列对象读取的文本中提取日期格式。我已经成功编写了用于提取所有复杂日期格式的正则表达式。
但是在将组提取为命名组时,我面临着巨大的痛苦。主要问题是我在表达中使用了非捕获组,因此很难将它们作为命名组。
我需要的输出是数据框的形式,其列为提取的整个日期,后跟年份,月份和日期。示例输入如下
df5 = pd.Series(
["04/20/2009","04/20/09","4/20/09","4/3/09","Mar-20-2009","Mar 20,2009","march 20,"Mar. 20,"Mar 20 2009","20 Mar 2009","20 march 2009","20 Mar. 2009","20 march,"Mar 20th,"Mar 21st,"Mar 22nd,"Feb 2009","Sep 2009","Oct 2010","6/2008","12/2009","2009","2010"])
我以前提取的表达式是
df5.str.extractall(r'((?:\d{1,2})?[/ ]*?(?:(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z\.,-/]*)?(?:\d{1,2}[a-z,-/]*)?\d{2,4})')
我无法执行将日期拆分为年,月和日的后续步骤。我尝试使用 re.compile和re.search 进行拆分,但是我无法理解它引发的错误,
TypeError:无法在类似字节的对象上使用字符串模式。
任何建议都将受到欢迎。 附注:我从类似的问题中观察了很多来自stackoverflow的类似性质的问题 sample 1,sample 2。我要提取的日期格式非常复杂,并且已经尝试了将近一周的时间,因此请不要轻易将其作为重复项来解决。
解决方法
回答实际目标:
您可以使用预先存在的功能来代替正则表达式吗?如果是这样,则只需使用pd.to_datetime
。它成功解析了您的样本数据
pd.to_datetime(df5)
# outputs:
0 2009-04-20
1 2009-04-20
2 2009-04-20
3 2009-04-03
4 2009-03-20
5 2009-03-20
6 2009-03-20
7 2009-03-20
8 2009-03-20
9 2009-03-20
10 2009-03-20
11 2009-03-20
12 2009-03-20
13 2009-03-20
14 2009-03-21
15 2009-03-22
16 2009-02-01
17 2009-09-01
18 2010-10-01
19 2008-06-01
20 2009-12-01
21 2009-01-01
22 2010-01-01
dtype: datetime64[ns]
要提取日期成分,可以使用.dt
访问器
完整解决方案示例,产生一个数据框:
pd.concat([
df5.rename('date_str'),pd.to_datetime(df5).dt.year.rename('year'),pd.to_datetime(df5).dt.month.rename('month'),pd.to_datetime(df5).dt.date.rename('date')
],axis=1)
date_str year month date
0 04/20/2009 2009 4 2009-04-20
1 04/20/09 2009 4 2009-04-20
2 4/20/09 2009 4 2009-04-20
3 4/3/09 2009 4 2009-04-03
4 Mar-20-2009 2009 3 2009-03-20
5 Mar 20,2009 2009 3 2009-03-20
6 March 20,2009 2009 3 2009-03-20
7 Mar. 20,2009 2009 3 2009-03-20
8 Mar 20 2009 2009 3 2009-03-20
9 20 Mar 2009 2009 3 2009-03-20
10 20 March 2009 2009 3 2009-03-20
11 20 Mar. 2009 2009 3 2009-03-20
12 20 March,2009 2009 3 2009-03-20
13 Mar 20th,2009 2009 3 2009-03-20
14 Mar 21st,2009 2009 3 2009-03-21
15 Mar 22nd,2009 2009 3 2009-03-22
16 Feb 2009 2009 2 2009-02-01
17 Sep 2009 2009 9 2009-09-01
18 Oct 2010 2010 10 2010-10-01
19 6/2008 2008 6 2008-06-01
20 12/2009 2009 12 2009-12-01
21 2009 2009 1 2009-01-01
22 2010 2010 1 2010-01-01
TypeError:无法在类似字节的对象上使用字符串模式。
此错误表明列的类型为bytes
,而不是str
。
此示例代码将引发相同的异常
re.findall('hello',b'hello kitty')
字节必须与字节进行模式匹配,或者先解码为str,然后再与字符串模式进行模式匹配,因此, fix 上面一行的两种方法是用b'hello'
或将源字符串解码为某种形式(例如b'hello kitty'.decode('ascii') # 'utf8' would also work
)。
要将字节列解码为str,可以使用str
访问器并使用如上所示的`decode方法
示例
df5.str.decode('utf8')
但是,我不确定您的正则表达式是否可以正常工作,但是由于我相信可以用更少的复杂性来实现您的目标,因此我没有尝试修复该问题。