详解大数据处理思路


简单的TopK问题

  1. 要求:海量整数(内存中无法全部装下),找出其中值最大的K个数据。
  2. 思路:首先读入前K个数据,使其形成一个大小为K的最小堆,初始默认这个就是值最大的K个数据,后面对其进行修改。因此需要依次读入其他剩余的所有数据,读入一个数据时就与最小堆的根节点进行比较,如果小于根节点,那么说明一定不是最大的K个值之一,舍弃即可;如果大于根节点,那么说明该值有可能是最大的K个之一,用这个值替换掉最小堆的根节点,然后调整最小堆使其重新符合性质。遍历结束以后的最小堆即是最终最大的K个数据。

大量可重复数据(内存中无法全部装下)中出现次数最多的K条数据

详细思路

  1. 分析:乍一看好像和topK问题十分相似,唯一的区别是topK中是值最大的K个,而这里是频率最高的K个数据,值大小的判断是很方便的,如果我们已经知道了所有数据出现的次数,那么这个就可以使用topK的思路来解决。
  2. 因此问题可以转化为如何求得大量数据中每个数据的出现次数。首先,不可能将全部数据都读入内存,然后再进行遍历统计,那可不可以建立一个哈希表,存储每个数据的出现次数呢?。设想,我们需要依次读入所有的数据,如果该数据第一次出现,那么我们就需要根据映射函数找到对应的位置,并将数组中该位置记录的对应次数为1;如果该数据出现过,我们只需要将对应位置的次数+1。这样做乍一看好像是可以的,因为并不需要将大量数据一次性全部装入内存进行处理,但是不能忽略的一点是哈希表是需要占用空间的,我们要处理的是海量数据,最极端的情况是没有完全相同的数据,那就会导致很严重的问题:内存中无法装下如此巨大的哈希表,不过如果数据大量重复,以至于内存可以装下哈希表,这其实也是可以的。但是,由于我们起初并不知道数据重复的程度,因此这种方法是不可行的。但是,大的哈希表内存无法装下,我们可以考虑小的哈希表啊!这就引出了切分文件的想法。并且必须保证所有相同的数据都得在同一个哈希表中进行统计,否则会导致数据哈希统计没有意义。同一个哈希表,就意味着必须在同一个小文件中。
  3. 因此,问题转化为如何将大量数据中按照同样的数据进行划分呢?这里便容易想到hash的方法,具体做法是依次读入大文件的每个数据,然后利用其值作为key,通过哈希函数求得其hash值,并将哈希值对某一个值(划分小文件的大小)取余,并将取余后的结果作为小文件的下标,将数据装入对应的文件中。这样全部处理结束后,相同的数据就一定在同一个小文件中了。
  4. 接下来,就像2中所说,我们依次处理每个小文件,利用内存完全可以装下的hash_map记录小文件中每种数据的出现次数即可。这样,就利用topK的思想,计算得到每个小文件中出现次数最多的K个数据。将每个文件中出现次数最多的K个数据记录下来,重新放入另一个文件中(只保留K个数据和其对应的出现次数),
  5. 假设最终有N个这样的小文件,每个文件保存K个数据和其对应的出现次数,我们要求的是这K*N个数据中出现次数最多的K个数据。到这里,问题就简单了,对N个文件进行归并处理即可。最终再归并处理所有的小文件,得到出现次数最多的K个数据。

总结

整体思路:分而治之 + hash统计 + 堆排序
分而治之并不是必要条件,需要判断当前数据量所对应的哈希表是否能在内存中装下,如果可以则不需要。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值