关于去重:文件数据去重示例

【摘要】本文介绍小文件与大文件在进行数据去重时的几种解决方法,比方按整行或要害列去除反复数据或留下反复数据,并用 esProc SPL 举例实现。请点击文件数据去重示例理解详情 在数据处理业务中,有时须要革除文件中的反复数据或只留下反复数据,本文将从小文件、大文件两方面介绍整行去重、要害列去重的几种解决方法,并提供用 esProc SPL 编写的代码示例。esProc 是业余的数据计算引擎,SPL 中有一套欠缺的汇合运算畛域的函数库,很适宜解决文件去重,写出的代码十分简洁。 1. 小文件1.1 整行去重有一个文本文件,其每一行是一个字符串,要将文件中的反复行只保留一行。解决此问题能够把文件的每一行读成一个字符串,组成一个汇合,而后通过汇合去重运算得出后果。 示例:报名绘画兴趣班的同学学号姓名记录在 paint.txt 中,可能有些同学报了屡次,请删除文件中反复的报名后保留在 paint1.txt 中。原文件局部数据如下所示    20121102-Joan    20121107-Jack    20121113-Mike    20121107-Jack esProc SPL 脚本如下: 1.2 要害列比拟一个文件,有多列数据,第一行是列名,第二行开始是数据记录,要对文件中要害列的内容进行比拟,对要害列内容反复的行进行删除或只保留反复的行。 现有 2018 年的销售订单表 order_2018.xlsx,局部数据如下所示: 1.2.1. 去除反复示例 1:申请出 2018 年购买产品的所有不同的客户 Id,保留在文件 2018c.xlsx 中。 esProc SPL 脚本如下: 示例 2:申请出 2018 年各位客户购买了哪些不同产品,将 CustomerId 和 ProductId 保留在文件 2018c_p.xlsx 中。 esProc SPL 脚本如下: 1.2.2. 只保留反复示例:申请出 2018 年回头客 (即屡次购买同种产品的客户) 的订单状况,将后果保留在文件 2018c_rebuy.xlsx 中。 ...

November 20, 2020 · 1 min · jiezi

数据库根据指定字段去重

需求:对一张用户表根据name/email/card_num字段去除重复数据; 思路:用group by方法可以查询出'去重'后的数据,将这些数据存储到一张临时表中,然后将临时表的数据存储到指定的表中; 误区及解决方案:group by方法只能获取部分字段(去重指定字段),不能一次获取到完整的数据,但是可以通过max函数获取group by结果集中的id,再根据id集合查询出全部的记录。 测试思路查询去重后的数据SELECT max(id) as id,name,email,card_num FROM users GROUP BY name,email,card_num; 从去重后的数据中获取id集合SELECT ID from (SELECT max(id) as id,name,email,card_num FROM users GROUP BY name,email,card_num) as T; 根据去重后的数据中获取id集合,从源数据中获得记录列表SELECT * from users where id in (SELECT ID from (SELECT max(id) as id,name,email,card_num FROM users GROUP BY name,email,card_num) as T); 实际方法根据去重后的数据中获取id集合,从源数据中获得记录列表,将这些列表数据存入一个临时表中create TEMP TABLE tmp_data as SELECT * from users where id in (SELECT ID from (SELECT max(id) as id,name,email,card_num FROM users GROUP BY name,email,card_num) as T); ...

June 19, 2019 · 1 min · jiezi

跟underscore一起学数组去重

引子数组去重是一个老生常谈的话题,在面试中也经常会被问道。对于去重,有两种主流思想:先排序,线性遍历后去重,时间复杂度O(n*log2n);使用哈希,空间换时间,时间复杂度O(n);上一篇文章,我分析了underscore的函数是如何组织的,我们能够依照这种方法书写自己的函数库,这篇文章,来看看关于函数去重underscore是如何做的?Underscore的去重功能介绍underscore的去重是指数组(Arrays)中uniq函数,其API如下:uniq .uniq(array, [isSorted], [iteratee]) 别名: unique 说明:返回 array去重后的副本, 使用 === 做相等测试. 如果您确定 array 已经排序, 那么给 isSorted 参数传递 true值, 此函数将运行的更快的算法. 如果要处理对象元素, 传参 iterator 来获取要对比的属性.上述API主要想说明几点:返回数组副本,不影响原数组相等的标准是a===b,表明不仅要值相等,类型也需要相等如果数组是排序的,去重运算效率更高uniq也可以比较对象,前提是需要指定比较的对象属性我们简单使用以下.uniq(array, [isSorted], [iteratee]),如下: console.log(.uniq([1,4,2,2,3,3])); console.log(.uniq([1,2,2,2,3,3],true)); console.log(.uniq([{ name:1, gender:“male” },{ name:2, gender:“female” },{ name:2, gender:“male” },{ name:4, gender:“male” }],true,“gender”));结果如下:去重思想及实现underscore去重的核心思想:新建结果集数组res,遍历待去重数组,将每个遍历值在res数组中遍历检查,将不存在当前res中的遍历值压入res中,最后输出res数组。 function uniq(array){ var res = []; array.forEach(function(element) { if(res.indexOf(element)<0){ res.push(element); } }, this); return res; } console.log(uniq([1,4,2,2,3,3])); //[1,4,2,3]其中如果数组是排序的,去重运算效率更高,因为排序能够将相同的数排列在一起,方便前后比较。 function uniq(array, isSorted) { var res = []; var seen = null; array.forEach(function (element,index) { if (isSorted) { //当数组有序 if(!index || seen !== element) res.push(element); seen = element; } else { if (res.indexOf(element) < 0) { res.push(element); } } }, this); return res; } console.log(uniq([1,2,“2”,3,3,3,5],true)); //(5) [1, 2, “2”, 3, 5]对于对象的去重,我们知道{}==={}为false,所以使用===比较对象在实际场景中没有意义。 在这里我举个实际场景的例子:我要在小组中选择一名男生(male)和一名女生(female),小组组员情况如下:var array = [{ name:“Tom”, gender:“female”},{ name:“Lucy”, gender:“female”},{ name:“Edward”, gender:“male”},{ name:“Molly”, gender:“female”}] 我们修改上面的uniq: function uniq(array, isSorted, iteratee) { var res = []; var seen = []; array.forEach(function (element, index) { if (iteratee) { //判断iteratee是否存在,存在的话,取出真正要比较的属性 var computed = element[iteratee]; if (seen.indexOf(computed) < 0) { seen.push(computed); res.push(element); } } else if (isSorted) { //当数组有序 if (!index || seen !== element) res.push(element); seen = element; } else { if (res.indexOf(element) < 0) { res.push(element); } } }, this); return res; } console.log(uniq([{ name:“Tom”, gender:“female” },{ name:“Lucy”, gender:“female” },{ name:“Edward”, gender:“male” },{ name:“Molly”, gender:“female” }],true,“gender”)); 结果如下: underscore的uniq的实现,基本上使用的上述思想。在附录中我附上了源码和一些注释。关于去重的思考上述我分析了underscore的uniq函数实现,在这之前我也看过诸如《JavaScript去重的N种方法》…之类的文章,underscore中的uniq函数实现方法并不是最优解,至少从时间复杂度来讲不是最优。 那么为什么underscore不用Set对象来解决去重问题,使用indexof查找的时间复杂度是O(n),而hash查询是O(1)。 我个人认为Set是ES6中引的对象,underscore是为了考虑兼容性问题。 那为什么不用obj作为Set的替代方案呢? 这里我猜是underscore的设计者只想用自己内部实现的.indexOf函数。此处是我的猜测,大家如果有想法,欢迎大家留言! 下面我附上ES6的实现(大家最熟悉的):var a = [1,1,2,3,4,4];var res = […new Set(a)];再附上obj的实现: function uniq(array,iteratee){ var res = []; var obj = {}; array.forEach(function(element) { var computed = element; if(iteratee) computed = element[iteratee]; if(!obj.hasOwnProperty(computed)) obj[(typeof computed)+""+JSON.stringify(computed)] = element; }, this); for(var p in obj){ res.push(obj[p]); } return res; } uniq([1,“1”,2,3,4,4]);// (5) [1, “1”, 2, 3, 4]附录underscore的uniq函数源码及注释: .uniq = .unique = function(array, isSorted, iteratee, context) { if (array == null) return []; if (!.isBoolean(isSorted)) { //如果没有排序 context = iteratee; iteratee = isSorted; isSorted = false; } /** ** 此处.iteratee ** function (key){ * return function(obj){ * return obj[key]; * } ** } ** key就是这里的iteratee(对象的属性),这里使用了闭包 **/ if (iteratee != null) iteratee = .iteratee(iteratee, context); var result = [];//返回去重后的数组(副本) var seen = []; for (var i = 0, length = array.length; i < length; i++) { var value = array[i];//当前比较值 if (isSorted) { //如果i=0时,或者seen(上一个值)不等于当前值,放入去重数组中 if (!i || seen !== value) result.push(value); seen = value;//保存当前值,用于下一次比较 } else if (iteratee) { var computed = iteratee(value, i, array); if (.indexOf(seen, computed) < 0) { seen.push(computed); result.push(value); } } else if (.indexOf(result, value) < 0) { result.push(value); } } return result; }; ...

March 15, 2019 · 2 min · jiezi