我有一个df
,
inv_id
W/E FEB 8 2017
W/E JAN 24 2018
W/E MAR 11 18
W/E APR 09 17
2018 Q1
2011 Q2
inv_id
的值都是字符串。值具有以下格式(strftime
)
%b %d %Y
%b %d %y
%b %d(non zero padded) %Y
%b %d(non zero padded) %y
%Y Q\d(regex decimal)
在strftime
中找不到一个非填充月份的指令。
我想知道如何定义模式并使用pandas
来识别它们,也许是pandas.Series.str.contains
?所以结果看起来像
inv_id is_date
W/E FEB 8 2017 True
W/E JAN 24 2018 True
W/E MAR 11 18 True
W/E APR 09 17 True
2018 Q1 True
2011 Q2 True
更新。设法处理第二种情况,
df['inv_id'].str.contains(pat=r'\b(19|20)\d{2} Q\d{1}\b', regex=True)
答案 0 :(得分:2)
您可能会发疯,使用更新的regex
模块并利用子例程。
在这里,我们首先可以想到简单的砖块,然后将它们以可能的格式(由我命名为format1
,format2
,... formatn
)粘在一起。
看到这段可爱的代码:
(?(DEFINE)
(?<month>JAN|FEB|MAR|APR)
(?<day>\b\d{1,2}\b)
(?<year>\b[12]\d{3}\b)
(?<year_short>\b[012]\d\b)
(?<quarter>Q[1234])
(?<ws>\s*)
# here comes the fun part
(?<format1>(?&month)(?&ws)(?&day)(?&ws)(?:(?&year)|(?&year_short)))
(?<format2>(?&year)(?&ws)(?&quarter))
# check for any existance
(?<formats>(?&format1)|(?&format2))
)
^(?=.*?(?&formats))
还有a demo on regex101.com。这需要通过应用的功能进行检查:
def check_format(string):
if re.search(pattern, string):
return True
return False
df['is_date'] = df['inv_id'].apply(check_format)
import pandas as pd, regex as re
d = {'inv_id': ['W/E FEB 8 2017', 'W/E JAN 24 2018', 'W/E MAR 11 18', 'W/E APR 09 17', '2018 Q1', '2011 Q2', 'somejunk', 'garbage in here']}
df = pd.DataFrame(d)
rx = re.compile(r'''the pattern from above''', re.VERBOSE)
def check_format(string):
return True if rx.search(string) else False
df['is_date'] = df['inv_id'].apply(check_format)
print(df)
哪个会产生
inv_id is_date
0 W/E FEB 8 2017 True
1 W/E JAN 24 2018 True
2 W/E MAR 11 18 True
3 W/E APR 09 17 True
4 2018 Q1 True
5 2011 Q2 True
6 somejunk False
7 garbage in here False
答案 1 :(得分:1)
您只需要一个复杂的正则表达式即可。
df['is_date'] = df['inv_id'].str.contains('^W/E\s+[A-Z]{3}\s+\d{1,2}\s+\d{2,4}$|^\d{4}\s+Q[1-4]$')