对于超大文件也就是无法一次性加载到内存,行数据是 key:value,统计同一个,key 的不同 value 个数,并输出到文件,格式为 key:n,输出的文件假设也很大,也无法加载到内存中,求思路
1 zynlp 2018-06-11 10:46:02 +08:00 via iPhone 这种活就交给 python 吧 |
![]() | 3 araraloren 2018-06-11 10:47:57 +08:00 思路不就是读多少处理多少么。。 |
![]() | 4 huiyadanli 2018-06-11 10:48:14 +08:00 把超大文件处理到数据库中,然后用 sql 统计数据 |
5 wplct 2018-06-11 10:48:20 +08:00 java 不是可以按行读取么 |
6 wplct 2018-06-11 10:51:20 +08:00 要不,先跑一边计数每个 key 有多少个 value,然后一个个 key 分开处理,慢是慢些 |
7 xylophone21 2018-06-11 10:59:16 +08:00 超大是多大?目的是什么?(考试还是工程) 如果是工程问题,最简单的方法其实是转嫁矛盾,读一行,写一条数据到文件行不行?文件不好查找,直接用数据库行不行?数据库还不够,分表行不行?分表还不行,用跟牛 X 的数据库分表啊。 如果是考试,那就往 hadoop 生态,MapReduce 上扯。 |
8 MrXiong OP @xylophone21 直接上 MapReduce 进行处理? |
![]() | 9 EchoUtopia 2018-06-11 11:01:53 +08:00 postgres: insert into words_count(word) values('example') on conflict do update count=words_count.count + 1 returning id |
10 wplct 2018-06-11 11:02:12 +08:00 all_key = {} with open('f.text') as f: key = f.readline().split(':')[0] if key not in all_key: all_key[key] = 0 all_key[key] += 1 result = {} for key in all_key.keys(): values = set() with open('f.text') as f: key, value = f.readline().split(':') if key == key: values.add(value) result[key] = len(values) |
11 wplct 2018-06-11 11:02:48 +08:00 你可以再改成一次跑多个 key 的统计, |
![]() | 12 EchoUtopia 2018-06-11 11:02:57 +08:00 postgres: insert into words_count(word) values('example') on conflict do update set count=words_count.count + 1 returning id |
![]() | 13 FreeEx 2018-06-11 11:12:10 +08:00 流处理了解一下 |
14 kaiser1992 2018-06-11 11:14:17 +08:00 Java 读取文件哪有一次性加载到内存的 |
![]() | 15 EchoUtopia 2018-06-11 11:15:58 +08:00 https://github.com/EchoUtopia/my-python-practices/blob/master/trie.js 之前用 js 统计了《心理学与生活》这本书的词频,用的前缀树,这本书纯文字只有 1M 多,我用 js 读取整本书、将单词插入前缀树、搜索一个单词、列出单词的频次并按照频次排序,所有操作加起来不到 0.5 秒。 |
![]() | 16 BBCCBB 2018-06-11 11:24:20 +08:00 bufferreader 啊, 不都是流处理吗? |
![]() | 17 SoCrazyStone 2018-06-11 11:57:17 +08:00 Java 直接读就可以吧,不是一次加载进内存,然后存到数据库里,结束了再导到文件? |
18 wplct 2018-06-11 12:35:56 +08:00 @EchoUtopia #15 想啥呢,内存放不下,应该是 gb 量级了 |
![]() | 19 pathbox 2018-06-11 12:42:33 +08:00 via iPhone 一行一行的 read 处理 就没有大文件内存限制了 |
![]() | 20 rrfeng 2018-06-11 12:44:17 +08:00 awk '!a[key:value]{n[key]++}END{for(i in n)print i,n[i]}' |
![]() | 21 rockyou12 2018-06-11 12:50:10 +08:00 lz 怕是从来没写过 java 的文件操作,如果直接用 stream 来读,本来就该用个小的 buffer 来读。不然直接用 nio 的 readline 就行了。自己谷歌下 java nio read file |
![]() | 22 CoderGeek 2018-06-11 12:55:49 +08:00 ...一行一行就好了 |
![]() | 23 EchoUtopia 2018-06-11 12:57:22 +08:00 @wplct #18 文件上 gb 量级不代表前缀树也有这么大。。 |
24 wplct 2018-06-11 12:59:48 +08:00 楼上的,楼主不是流式处理 ,是因为这个需求需要去重,一次性处理内存可能不够 |
25 panpanpan 2018-06-11 13:14:35 +08:00 via iPhone 导进数据库里面 group by 一下难道不是最简单的方式? |
![]() | 27 xmh51 2018-06-11 13:21:15 +08:00 分而治之 把大文件拆分掉成 N 份 每份都计算 key 的 value count 值(需要带上 value ),然后把 key 按 hashcode 计算得到文件里面。最后合并结果文件 |
![]() | 28 xmh51 2018-06-11 13:21:57 +08:00 感觉像算法题 果然是算法题 ...... |
![]() | 29 xmh51 2018-06-11 13:24:36 +08:00 优化下 分而治之 读大文件不用拆分,一行一行读即可,直接计算 hashcode,把 key value 直接放到 N 份文件中的指定一个文件中。然后直接计算结果,最后合并结果 |
![]() | 31 verrickt 2018-06-11 13:29:31 +08:00 via Android ![]() 先对文件用外部排序按 key 排序。然后读一行,看下一行的 key,一样的话加计数,不一样把计数写到输出文件里。大体上还是外部排序+归并的思路 |
![]() | 32 xmh51 2018-06-11 13:42:58 +08:00 @MrXiong 去重在 hash 之后的一个步骤。一共两次 第一次 归并 key value 到指定文档,第二次 去重计算 count |
![]() | 33 xmh51 2018-06-11 13:46:19 +08:00 @MrXiong 第一次 归并 key value 到指定的 n 个文件中(保证 key 相同的数据在同一个文件中,可以用 hashcode 分),第二次 去重计算 count,最好合并结果 |
![]() | 34 20015jjw 2018-06-11 14:00:39 +08:00 via Android data base 课最基本的内容吧 |
35 dangluren 2018-06-11 14:27:04 +08:00 你好,这种问题,就和 mapreduce 类似了。如果你不用 mapreduce,可以这样做(其实也是 mapreduce 的原理) 假如数据有 10G,你内存 1G, 假设比较均匀,不存在数据倾斜情况(倾斜不能太严重)。 1. 你先一行一行的读取,然后得到 key 的 hashcode, 然后对%20,得到的数是几,就写到第几个文件去。 2. 由第一步你就得到了 20 个文件了,如果数据没倾斜,大概一个就 500M, 这时候同一个 key 的肯定在同一个文件,进行处理就可以了。 3. 如果有点数据倾斜,就%30, %50 的尝试。如果某一个 key 就超过了 1G,某个 key 很大的情况下,你可以先把这个 key 过滤出来,写入到一个文件中,然后再使用布隆过滤器或者其他什么方法 |
36 kaiser1992 2018-06-11 15:11:48 +08:00 采用分治思想,借助 Hadoop |
![]() | 37 qingfengxm 2018-06-11 15:11:53 +08:00 不知道你说的超大文件有多大? 10G 还是 10T。你这说的其实就是大数据单词计数,mapreduce 或者 spark 搞定 |
![]() | 38 dif 2018-06-14 19:14:13 +08:00 mapreduce |