免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4551 | 回复: 8
打印 上一主题 下一主题

请教对过亿文本文件过滤重复的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-03-02 15:25 |只看该作者 |倒序浏览
1.出现上亿(大小过G)的文本文件本来就是不正常的事情
2.如何在1G内存里完成这个任务


问题是这样的:一个文本文件.记录过亿(超过1亿的行数).如何在1G的内存里完成过滤重复.

大概的思路 分N份. 分别对这N份过滤重复. 然后 再循环 N^2 次.
  有更好的方法么


P.S.  因为一次读入会超过2G或者4G. 所以不能一次读入. 另外.
  千万级别我试过. 可以用set()的方法在 6s 内完成.

论坛徽章:
0
2 [报告]
发表于 2010-03-02 15:30 |只看该作者
给出一条记录来看下

论坛徽章:
0
3 [报告]
发表于 2010-03-02 16:10 |只看该作者
思路这样看看可以不可以:做个指针,以及指针记录临时文件,然后读1M进行过滤;然后再读1M进行过滤.当然这个1M不是一定的,用二分法,找出一次读出的最佳文件大小.
当然,也可以考虑用多线程.

论坛徽章:
0
4 [报告]
发表于 2010-03-02 16:27 |只看该作者
  1. #!/usr/bin/env python
  2. import os
  3. import glob
  4. import shutil
  5. import string
  6. keyList = string.letters+string.digits+'_'
  7. shutil.rmtree('.tmplogs')
  8. os.mkdir('.tmplogs')
  9. tmpFileList = {}
  10. taskList = []

  11. # part1
  12. for f in keyList:
  13.     tmpFileList[f] = open('.tmplogs/%s'%f,'a')

  14. fd = open('all')
  15. while True:
  16.     lines = fd.readlines(1024)
  17.     if not lines: break
  18.     for line in lines:
  19.         line = line.strip()
  20.         k = line[0]
  21.         try:
  22.             if k in keyList:
  23.                 tmpFileList[k].write('%s\n'%line)
  24.             else:
  25.                 tmpFileList['_'].write('%s\n'%line)
  26.         except:
  27.             continue
  28. fd.close()

  29. for f in keyList:
  30.     tmpFileList[f].close()

  31. # part2
  32. taskList = glob.glob('.tmplogs/*')
  33. logsFile = open('done.log','a')
  34. for task in taskList:
  35.     fd = open(task)
  36.     tmpDict = {}
  37.     while True:
  38.         lines = fd.readlines(1024)
  39.         if not lines: break
  40.         for line in lines:
  41.             line = line.strip()
  42.             tmpDict[line] = None
  43.     fd.close()

  44.     for k in tmpDict:
  45.         logsFile.write('%s\n'%k)
  46.    
  47. logsFile.close()
复制代码
我觉得主要看要过滤的原始数据是如何吧,如果是IP的话,算法上有很大改进的空间。(以上代码,仅供参考)

论坛徽章:
0
5 [报告]
发表于 2010-03-02 20:58 |只看该作者
本帖最后由 starfuck 于 2019-11-26 23:34 编辑












论坛徽章:
0
6 [报告]
发表于 2010-03-03 11:11 |只看该作者
你可以尝试linux自带的uniq就可以完美解决...

help一下把。。。10G都不是问题,很快。

论坛徽章:
0
7 [报告]
发表于 2010-03-03 23:52 |只看该作者
给个笨方法,呵呵,不过只能剔除重复行
import bsddb
def rmvrpt(srcfile):
    bdbf=bsddb.btopen(srcfile+'bdb')
    for ln in open(srcfile,'rb'):
        bdbf.setdefault(ln,'')
    fout=open(srcfile+'.res','wb')
    for i in bdbf:
        fout.write(i)
    bdbf.close()
    os.remove(srcfile+'bdb')
    return

论坛徽章:
0
8 [报告]
发表于 2010-03-07 19:16 |只看该作者
用数据库多简单?

论坛徽章:
0
9 [报告]
发表于 2010-03-07 21:03 |只看该作者
{:3_196:}不会是做短信分析吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP