Openrefine 使用正则表达式清理F1数据
1.从F1网页中提取数据
在网页中有F1分站赛的处罚信息,这些信息以条目的形式出现,我们的目的是:在openrefine中,将这些条目数据利用正则表达式提取出来,生成结构化表格,以便于后期的分析。
image-20201023131403690.png
2.新建refine项目,选择剪切板的方式,将数据粘贴过来
image-20201023131307863.png
3.将保留空白行去掉
image-20201023131846938.png
image-20201023132213980.png
4.数据清洗
4.1生成包含比赛名称的列
if(value.contains('Prix'),value,"")
#根据Column1列新建一列 命名为race列
#contains(value,"Prix")返回的是TRUE or False,如果字符串中包含Prix字符,返回True,race列取值为value,否则取值为空字符串
#选race列,向下填充,将空格填充满
image-20201023133041012.png
image-20201023133337521.png
4.2 生成处罚通知的列
if(contains(value,'Prix'),'',value)
image-20201023133946822.png
检查数据发现在56-59行出现了归类错误,主要原因是在处罚信息里包含了完整的比赛名称,由于量不是很大,可以直接用edit进行编辑。
编辑前:
image-20201023135007560.png
编辑后:
image-20201023135523204.png
4.3去除同一条数据跨多行的情况
检查发现,在penalty notice列中存在着一条数据分布在多行的情况,要将这种情况去除
image-20201023140111965.png
解决方法:
image-20201023140539264.png
输入正则表达式:^[^-]
#含义是:匹配开头不是"-"的值,记住行号并用edit对单元格进行剪切-复制更改
image-20201023140948599.png
penalty notice列,选择空白行,删除行
image-20201023142539940.png
image-20201023142622953.png
4.4 提取车手和车队名称
基于penalty notice列,新建列
image-20201023143412005.png
使用Java正则语法:
value.match(/- (.*?)\s\(([\w ]+)\)?.*/).join('::')
注意:
1.'-'后面的空格
2.用'?'将贪婪模式改为非贪婪模式
3.\( \)转义为普通括号
4.()代表分组,返回括号内的值,本例中是两个字符串
5.match()匹配字符串,并返回括号中的值
使用python正则语法:
#import re
#return re.findall("- (.*)\s\((\w+)\)",value)
#import re
#text=re.search("- (.*)\s\((\w+)\)",value)
#return text.group(1)+'::'+text.group(2)
image-20201023150323933.png
对车手车队列进行分面,检查提取的结果,发现有的行没有提取到信息,原因是没有 车手(车队)这种模式的字符串,手动更改单元格,删除Protest re Pirelli test行
image-20201023152028704.png
image-20201023152117044.png
image-20201023152701739.png
4.5将车手车队列分成车手、车队两列(::分割)
image-20201023152932974.png
4.6提取罚金
value.replace(',','').match(/.*€(\d+)/)[0]
#先将2,800中的','去掉再匹配正则
image-20201023155236449.png
分面检查发现有的罚金没有提取出来(Java正则提取不出来,原因未知,后改用python正则),接下来再提取一次,选择罚金列中空的行,根据penalty notice 新建一列罚金2
value.replace('€',':').replace(',','')
image-20201023164915299.png
选择罚金2,新建一列罚金1,使用python正则表达式
import re
return re.findall(".*:(\d+)",value)[0]
image-20201023165718115.png
合并罚金列和罚金1列
image-20201023170007040.png
image-20201023170048670.png
4.7提取比赛阶段
比赛阶段主要有FP...或者Q...或者qualifying
value.match(/(?i).*((FP\d+)|(Q\d+)|(qualifying)).*/)[0]
#(?i)表示整体不区分大小写
image-20201023173509347.png
4.8提取速度
value.match(/.*?(\d+\.?\d+)\skm\/h.*/)[0]
image-20201023175110849.png