一种数据清洗方法及系统

文档序号:29419948发布日期:2022-03-26 14:03阅读:247来源:国知局
一种数据清洗方法及系统

1.本发明涉及数据处理技术领域,尤其涉及一种数据清洗方法及系统。


背景技术:

2.大数据技术通过对海量数据进行挖掘,分析出数据背后蕴藏的规律,大数据的处理流程通常包括数据采集、数据清洗、数据存储、数据分析与挖掘、数据可视化等流程;其中数据清洗是大数据处理的基础性操作,目的是消除不符合规范和要求的数据,数据清洗的效率将直接影响大数据的整个处理流程的速度。
3.大数据清洗的主要工作包括对缺失数据、格式错误数据、内容错误数据、不需要的数据、以及逻辑错误的数据进行处理;现有的大数据清洗技术面对海量的大数据清洗场景时,每个任务的执行时间较长,存在清洗效率不高的缺点。


技术实现要素:

4.本发明的目的在于克服现有技术中的不足,提供一种数据清洗方法及系统。
5.第一方面,本发明提供了一种数据清洗方法,包括:
6.获取原始数据集,通过多线程将原始数据集拆分为若干数据分片;
7.根据预先设置的清洗规则,对所述若干数据分片进行同步清洗,获得若干清洗数据分片;
8.合并处理所述若干清洗数据分片,获得完整的清洗数据集。
9.进一步的,所述通过多线程将原始数据集拆分为若干数据分片包括以下步骤:
10.步骤一:创造初始清洗任务单元,所述初始清洗任务单元的数据集为原始数据集;创建清洗任务队列,所述清洗任务队列支持fifo操作;
11.步骤二:将初始清洗任务单元与一个未被绑定清洗任务单元的线程绑定,获得线程1;
12.步骤三:将所述线程1插入所述清洗任务队列,获得线程1所对应的数据集;
13.步骤四:根据预设阈值,将步骤三所述数据集拆分为两个数据分片;
14.步骤五:创建两个清洗子任务单元,所述两个清洗子任务单元分别与步骤四所述两个数据分片绑定;
15.步骤六:将步骤五所述两个清洗子任务单元分别与一个未被绑定清洗任务单元的线程绑定,获得两个线程;
16.步骤七:将步骤六所述两个线程插入所述清洗任务队列,从而获得步骤六所述两个线程各自对应的数据集;
17.步骤八:对所述步骤七输出的两个线程各自对应的数据集,分别重复步骤四至步骤七,直至输出数据集阈值小于预设阈值。
18.进一步的,步骤四所述数据集通过split操作进行拆分。
19.进一步的,所述若干清洗数据分片通过merger操作进行逐层上报合并汇总。
20.第二方面,本发明还提供了一种数据清洗系统,包括:
21.清洗任务调度模块,用于通过多线程将原始数据集拆分为若干数据分片;
22.清洗任务执行模块,用于对所述清洗任务调度模块获得的若干数据分片进行同步清洗,并合并若干数据分片清洗结果,输出完整的清洗数据集。
23.进一步的,所述数据清洗系统还包括线程池管理模块,所述线程池管理模块用于维护管理多线程。
24.进一步的,所述原始数据集通过多线程和split函数拆分成若干数据分片。
25.进一步的,所述若干清洗数据分片通过merger操作进行逐层上报合并汇总。
26.与现有技术相比,本发明的有益效果为:本发明通过多线程将原始数据集拆分为若干数据分片,然后对若干数据分片进行同步处理,降低了清洗任务的执行时间,提高了清洗效率。
附图说明
27.图1是本发明实施例提供的数据方法工作流程图;
28.图2是本发明实施例提供的数据清洗系统工作流程图;
29.图3是本发明实施例提供的清洗任务单元二叉树框架图。
具体实施方式
30.下面结合附图对本发明作进一步描述。以下实施例仅用于更加清楚地说明本发明的技术方案,而不能以此来限制本发明的保护范围。
31.实施例1:
32.如图1所示,一种数据清洗方法,包括:
33.获取原始数据集,原始数据集为csv格式,内容定义如下:
34.h1,h2,

,hn
35.v11,v12,

,v1n
36.v21,v22,

,v2n
37.……
38.vn1,vn2,

,vnn
39.其中h1,h2,

,hn为表头字段,每个表头字段都对应多个数据,这些数据用v11,v12,

,vnn表示,每一行数据为一条记录。
40.创建初始清洗任务单元task1,定义初始清洗任务单元task1的数据集为data,data可表示为[begin,end],其中begin表示数据集的起始索引,end表示数据集的结束索引,此时由于task1为初始清洗任务,因此task1的数据集data即为原始数据集,task1的数据集data也可表示为[1,n]。
[0041]
创建清洗任务队列,清洗任务队列是由threadtask组成的集合,清洗任务队列支持fifo(first in first out)操作,即清洗任务调度模块只能从队列的头部插入节点,然后从队列的尾部取出节点。
[0042]
将初始清洗任务单元task1与未绑定任何清洗任务单元线程进行绑定,获得线程1,绑定了清洗任务单元的线程记为threadtask,线程1记为threadtask1,然后将线程1插入
清洗任务队列的头部。
[0043]
从清洗任务队列的尾部取出一个threadtask,获得threadtask对应的清洗任务单元task的数据集data[begin,end],此时清洗队列中只有一个初始清洗任务单元task1对应的线程,因此清洗任务调度模块从清洗任务队列的尾部取出的threadtask即为初始清洗任务单元task1对应的线程。
[0044]
计算task1的数据集data[begin,end]的差值sub,sub值等于end-begin的值,如果sub大于预先设定的原始数据分片的阈值x,表示该清洗任务task1对应的数据集data[begin,end]规模太大,需要进一步拆分为两个清洗数据分片,执行split操作,将清洗任务单元task1的数据集data[begin,end]拆分为数据分片[begin,sub/2]和[sub/2,end]。
[0045]
清洗任务单元task1创建清洗子任务单元task11和清洗子任务单元task12,分别将清洗子任务单元task11和数据分片[begin,sub/2]进行绑定,将清洗子任务单元task12和数据分片[sub/2,end]进行绑定,此时将清洗任务单元task1称为task11和task12的清洗父任务单元。
[0046]
清洗子任务单元task11和清洗子任务单元task12分别与一个未被绑定清洗任务单元的线程绑定,绑定形成threadtask2和threadtask3,然后将threadtask2和threadtask3插入到清洗任务队列头部。
[0047]
继续从清洗任务队列的尾部取出一个threadtask,并重复以上的处理流程,将清洗任务单元task的数据集data[begin,end]拆分为2个数据分片,并创建2个清洗子任务单元,然后将这2个数据分片分别绑定到这2个清洗任务单元,再将这2个清洗任务绑定到不同的线程,形成2个threadtask;最后将这2个threadtask分别插入到清洗任务队列中,直至sub小于预先设定的原始数据分片的阈值x,表示该清洗任务单元task对应的数据集data[begin,end]规模适中,可以执行清洗操作。
[0048]
清洗规则为yml格式(yet another markup language)的配置文件,其内容定义如下:
[0049]
name:规则名称
[0050]
description:规则描述信息
[0051]
condition:规则执行条件
[0052]
actions:
[0053]-规则执行动作1
[0054]-规则执行动作2
[0055]

[0056]-规则执行动作n
[0057]
其中,name字段表示规则名称,description字段表示规则描述信息,condition字段表示规则执行条件,actions字段表示规则执行动作,规则执行动作可以有多个。当condition指定的规则执行条件为真时,执行actions指定的规则执行动作。规则执行条件和规则执行动作在groovy脚本中定义。
[0058]
加载清洗规则文件,解析出condition字段和actions字段,然后加载数据集data[begin,end],使用condition字段指定的函数判断数据集data[begin,end]的每一条记录是否符合清洗条件,如果该函数返回值为真,则使用actions字段指定的函数对该记录进行
处理,最后将处理后的所有记录汇总,成生成清洗数据分片。
[0059]
condition字段指定的函数和actions字段指定的函数都在groovy脚本文件中定义,由清洗任务执行模块在初始化时加载。
[0060]
如图3所示,所有的清洗任务单元都有相应的清洗子任务单元或清洗父任务单元,并且清洗任务单元之间构成了一棵二叉树t,二叉树t的头节点即为初始清洗任务单元task1,生成清洗数据分片后,清洗任务单元task执行merge操作,将本任务的清洗数据分片上报给对应的清洗父任务单元;清洗父任务单元合并所有子任务单元上报的清洗数据分片形成清洗数据分片s,然后执行merge操作将清洗数据分片s上报给上一层的清洗父任务单元,重复以上操作,经过逐层上报汇总,最终由初始清洗任务单元task1汇总生成完整的清洗数据集,始清洗任务单元task1再将完整的清洗数据集导出生成清洗数据csv文件,这样就完成了所有的清洗任务。
[0061]
实施例2:
[0062]
如图2所示,本发明提供了一种数据清洗系统,包括线程池管理模块、清洗任务调度模块和清洗任务执行模块。
[0063]
定义原始数据文件.csv的内容如下:
[0064]
h1,h2,

,hn
[0065]
v11,v12,

,v1n
[0066]
v21,v22,

,v2n
[0067]
……
[0068]
vn1,vn2,

,vnn
[0069]
其中h1,h2,

,hn为表头字段,每个表头字段都对应多个数据,这些数据用v11,v12,

,vnn表示,每一行数据为一条记录。
[0070]
定义清洗规则文件rule.yml的内容如下:
[0071]
name:"rule1"
[0072]
description:"无效数据处理"
[0073]
condition:"isinvaliddata(h2)"
[0074]
actions:
[0075]-"delete()"
[0076]
rule.yml的isinvaliddata(h2)函数和delete()函数都定义在数据清洗模块1.groovy中,isinvaliddata(h2)函数的功能是判断h2字段对应的数据是否在[60,100]之间,如果在此范围内,则返回true,否则返回false。delete()函数的作用是删除csv数据文件中的指定记录。
[0077]
假设原始数据文件.csv的记录数为10,并且假设原始数据分片的阈值x为5。
[0078]
线程池管理模块通过executorservice接口创建线程池threadpool,threadpool可以表示为threadpool[t1,t2,

,tn],其中tk(其中k的取值范围为[1,n])为线程池threadpool创建的线程。
[0079]
清洗任务调度模块调用apache commons库加载原始数据集.csv,获得该文件的记录总数n的值为10,清洗任务调度模块通过继承jdk的抽象类recursivetask的方式创建初始清洗任务单元task1,设置task1数据集data的索引范围为[1,10]。
[0080]
清洗任务调度模块向线程池管理模块发起申请,由线程池管理模块遍历线程池threadpool[t1,t2,

,tn],获得一个未绑定任何清洗任务单元task的线程,记为线程1。
[0081]
清洗任务调度模块调用线程1的submit()函数将初始清洗任务单元task与线程1进行绑定形成threadtask1,然后调用jdk队列的add()函数将threadtask1插入到清洗任务队列中。清洗任务队列由清洗任务调度模块在初始化时通过jdk的类workqueue创建。
[0082]
清洗任务调度模块调用jdk队列的take()函数从清洗任务队列的尾部取出threadtask1,获得threadtask1对应的初始清洗任务单元task1的数据集data[1,10],然后计算task1数据集data[1,10]的差值sub为9。
[0083]
此时sub值大于原始数据分片的阈值x,表示该清洗任务单元task1对应的原始数据集规模太大,初始清洗任务单元task1调用recursivetask的split()函数将数据集data[1,10]拆分为数据分片[1,4]和数据分片[5,10];接着通过继承recursivetask的方式创建清洗子任务单元task11和清洗子任务单元task12,分别将清洗子任务单元task11和数据分片[1,4]进行绑定,将清洗子任务单元task12和数据分片[5,10]进行绑定。
[0084]
清洗任务调度模块向线程池管理模块发起送申请,由线程池管理模块遍历线程池threadpool[t1,t2,

,tn],获得两个未绑定任何清洗任务单元task的线程,记为线程2和线程3。
[0085]
清洗任务调度模块调用线程2的submit()函数将清洗子任务单元task11与线程2进行绑定形成threadtask2,调用线程3的submit()函数将清洗子任务单元task12与线程3进行绑定形成threadtask3,最后分别调用jdk队列的add()函数将threadtask2和threadtask3插入到清洗任务队列中等待执行。
[0086]
清洗任务调度模块调用jdk队列的take()函数从清洗任务队列的尾部取出threadtask2,threadtask2对应的清洗子任务单元task11的数据集data[1,4]的差值sub为3,sub值小于等于原始数据分片的阈值x,说明task11对应的数据集data[1,4]规模适中,可以执行清洗操作,task11调用清洗任务执行模块执行清洗操作。
[0087]
清洗任务执行模块调用compute()函数读取清洗规则文件rule.yml,然后加载java规则引擎rulesengine,通过rulesengine的file()函数对rule.yml实例化,将rule.yml的condition字段和actions字段转换为java函数。
[0088]
清洗任务执行模块的compute()函数再通过apache commons库加载数据集data[1,4],然后通过java规则引擎rulesengine调用rule.yml的isinvaliddata(h2)函数,遍历数据集data[1,4]的每一条记录r,判断记录r的h2字段对应的数据是否在[60,100]之间,如果在此范围,则返回true,否则返回false。
[0089]
清洗任务执模块的java规则引擎rulesengine判断isinvaliddata(h2)函数的返回值为true,则调用rule.yml的delete()函数将记录r删除,数据集data[1,4]的所有记录都使用清洗规则处理完成后,所有未被删除的记录r则为清洗后的有效数据,清洗任务执模块将这些清洗后的有效数据合并为清洗数据分片a返回给task11。
[0090]
task11执行merge操作,将清洗数据分片a上报给初始清洗任务task1,task1将清洗数据分片a插入集合set中。
[0091]
清洗任务调度模块调用jdk队列的take()函数从清洗任务队列的尾部取出threadtask3,threadtask3对应的清洗子任务单元task12的数据集data[5,10]的差值sub
为5,sub值小于等于原始数据分片的阈值x,说明task12对应的数据集data[5,10]规模适中,可以执行清洗操作,task12调用清洗任务执行模块执行清洗操作获得清洗数据分片b,其处理流程类似。
[0092]
task12执行merge操作,将清洗数据分片b上报给初始清洗任务单元task1,初始清洗任务单元task1将清洗数据分片b插入集合set中,初始清洗任务task1执行merge操作,遍历集合set,将清洗数据分片a和清洗数据分片b进行合并,形成完整的清洗数据集,然后调用apache commons库将完整的清洗数据集导出生成csv文件,这样就完成了所有的清洗任务。
[0093]
清洗任务task1、task11和task12执行merge操作后,清洗任务调度模块将清洗任务task1、task11和task12对应的threadtask退回给线程池管理模块,线程池管理模块删除清洗任务task1、task11和task12与相应的threadtask的绑定关系,然后将task1、task11和task12对应的线程插入到线程池中备用。
[0094]
本领域内的技术人员应明白,本技术的实施例可提供为方法、系统、或计算机程序产品。因此,本技术可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本技术可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、cd-rom、光学存储器等)上实施的计算机程序产品的形式。
[0095]
本技术是参照根据本技术实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
[0096]
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
[0097]
这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
[0098]
以上所述仅是本发明的优选实施方式,应当指出,对于本技术领域的普通技术人员来说,在不脱离本发明技术原理的前提下,还可以做出若干改进和变形,这些改进和变形也应视为本发明的保护范围。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1