1 亿条数据如何使用 Pandas 去重?

2016-09-07 15:14:44 +08:00
 zmrenwu
总数据量大概有 20G ,内存只有 8G ,无法一次载入内存。
查了下 pandas 的 read_csv 方法可以分块地读入数据,同时 DataFrame 对象有一个 unique 方法可以去重。但是好像只能对每一块已载入内存的数据去重,如何整体去重呢?
18902 次点击
所在节点    Python
41 条回复
liprais
2016-09-07 15:35:19 +08:00
装个数据库,弄到数据库里,让数据库帮你做这些事
数据库发展了二三十年了,对于这种操作优化的很好,比自己写算法实现轻松多了
xuqd
2016-09-07 15:39:44 +08:00
外排序
zmrenwu
2016-09-07 15:42:02 +08:00
@liprais 看来唯有如此,暂时找不到 pandas 下的解决方案。
xderam
2016-09-07 18:00:23 +08:00
呃,来个运维思维。用 uniq 和 awk 是否也可以?当然没考虑过效率。。
helloworld2010
2016-09-07 18:02:30 +08:00
分区段去重不就可以了,一块去重完,再合并到相邻块去重……不知道这思路可行么
Layne
2016-09-07 18:14:27 +08:00
@helloworld2010 只要最终去重后的数据量还是无法一次载入内存,应该还是达不到效果吧
9hills
2016-09-07 18:17:09 +08:00
@xderam 用 awk 就行了,不需要 uniq 。因为原理是 hash 表

1 亿条数据(和大小无关,和条数有关), 8G 内存应该差不多。 80B 一条,可能刚刚好
9hills
2016-09-07 18:18:20 +08:00
@9hills 这里有个错误, hash 表的大小是和最终去重后的条目有关的,和原始数据条目无关
Magic347
2016-09-07 18:18:54 +08:00
自己实现的话,显然采用 2 楼的方法,
1. 把原文件分块,分成 n 个小文件依次 load 进内存进行内存排序,并输出 n 个有序小文件
2. 对 n 个有序小文件执行 merge 操作,生成 1 个合并后的有序大文件
3. 逐行扫描该有序大文件,去除重复行数据即可

注意几点:
1. 分块以后的小文件大小要保证可以全量 load 进机器内存
2. merge 时,内存仅需维护一个 n 元素的二叉堆即可,开销大头在于磁盘 IO (因为要反复进行文件读写操作)

这应该是一道很经典的有关海量数据去重的面试题,
扩展到分布式计算领域,可以借鉴 Map-Reduce 的思想(如果楼主有兴趣进一步了解)。
vinceguo
2016-09-07 18:26:18 +08:00
@Magic347 MR 有什么好面试的,去重一条 PIG 就能做掉
hanzhichao2000
2016-09-07 18:37:20 +08:00
blaze 或 dask ,语法类似 pandas ,比数据库和 Hadoop 都轻
matrix67
2016-09-07 18:39:24 +08:00
又不是整天去,效率没关系。逃,
lll9p
2016-09-07 18:45:25 +08:00
推荐用数据库,比 Pandas 效率高
dl2k
2016-09-07 18:46:52 +08:00
其实本质上都会考虑用摘要方法来减少用于去重比较的数据量 不过摘要总归会遇到碰撞问题
而且如果数据规模极端点 摘要数据依然可能过大的可能 其实最通用的方法是先轮询一遍数据 根据一种可以避免把相同数据分在不同组的分组算法 比如 md5 后取模 把数据分成 n 个文件 每个文件小于内存大小 然后轮询这些文件进行单独去重 最后合并数据 这个方法大概需要和数据等量的磁盘空间
ooonme
2016-09-07 18:54:19 +08:00
会 python 的话 pyspark 一行代码搞定
zhangchioulin
2016-09-07 19:15:13 +08:00
@Layne 哈哈哈 ... 你的头像
renzhn
2016-09-07 19:32:49 +08:00
你可以:
1. 进对数据进行排序,此操作不需要大量内存,可以用 sort 命令
2. 过滤掉重复出现的行,可以只直接用 uniq -d
tolerance
2016-09-07 19:37:53 +08:00
Bloom Filter , bitmap
renzhn
2016-09-07 19:41:08 +08:00
第二步应该是 uniq -u
这两步操作都不需要把所有的数据读入内存
renzhn
2016-09-07 19:45:49 +08:00
不对 应该是无参数的 uniq

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/304568

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX