V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
oldbird
V2EX  ›  Python

如果对 2K 万条记录的某个字段查重?

  •  
  •   oldbird · 2020-05-16 22:34:35 +08:00 · 3225 次点击
    这是一个创建于 1655 天前的主题,其中的信息可能已经有所发展或是发生改变。

    库中有 N 张表,记录数总共 2000 万条,每张表都有一个 BSM 字段,想查找库里该字段是否有重复值,打印该重复值及所在的表名和 ID 号。

    环境:python2.7,32bit 。

    现在的做法是:在外部定义 defaultdict(list)类型的字典,遍历所有表格的记录,每条记录的 BSM 值为 key,表名+id 值为该 key 对应的 value (列表)中的项;最后再遍历字典,查找 value 中项数大于 1 的输出。

    运行后一段时间报 内存错误,请问有什么方法吗?

    13 条回复    2020-05-17 10:32:23 +08:00
    Vegetable
        1
    Vegetable  
       2020-05-16 22:39:29 +08:00
    https://github.com/search?l=Python&q=bloom&type=Repositories
    布隆过滤器(英语:Bloom Filter )是 1970 年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
    felix021
        2
    felix021  
       2020-05-16 22:41:54 +08:00 via Android
    2000 万不是大什么数据,学一点 c 吧同学。
    jun0205
        3
    jun0205  
       2020-05-16 22:44:10 +08:00
    2000W 不算多,把 N 张表的 BSM 、表名,ID 放在一个视图里面,然后 SQL Group by 应该会好点
    laminux29
        4
    laminux29  
       2020-05-16 22:46:56 +08:00
    不是学 C,而是要学数据结构与算法。

    内存不够的情况下,用外排序就行了。
    ackoly
        5
    ackoly  
       2020-05-16 22:59:29 +08:00
    SQL 处理不是更简单吗?
    ackoly
        6
    ackoly  
       2020-05-16 23:03:23 +08:00   ❤️ 2
    -- 如果 BSM 字段长度低于 32,不用做 md5,直接使用 BSM 字段就好
    -- 1. 创建汇总表
    create table data_total as
    select 1 as flag,id,BSM,md5(BSM) as md5_value from table_a union all
    select 2 as flag,id,BSM,md5(BSM) as md5_value from table_b union all
    select 3 as flag,id,BSM,md5(BSM) as md5_value from table_c union all
    select 4 as flag,id,BSM,md5(BSM) as md5_value from table_d union all
    select 5 as flag,id,BSM,md5(BSM) as md5_value from table_e
    ;

    -- 2. 查出哪些值有重复
    create table value_mult as
    select
    md5_value
    ,count(1) as cnt
    from data_total t1
    group by md5_value
    having count(1) > 1
    ;

    -- 3. 为 data_total 表创建索引
    CREATE INDEX ix_md5_value ON data_total(md5_value);

    -- 4. 查询出结果
    select t1.*
    from data_total t1
    inner join value_mult t2
    on t1.md5_value=t2.md5_value
    ;
    nuistzhou
        7
    nuistzhou  
       2020-05-16 23:12:44 +08:00 via iPhone
    不是,这玩意不是几行 SQL 就能解决的吗?为啥还要搞复杂用 python 处理呢? group by 然后 count 啥的不就 OK 了嘛?
    wiix
        8
    wiix  
       2020-05-16 23:22:53 +08:00
    如果是传统关系数据库,真就两条 sql 的事。
    anaf
        9
    anaf  
       2020-05-16 23:55:55 +08:00
    6 楼直接给了答案 看着没毛病 我还要想一下是不是这么写 说明我水平不够 6L 好 [逃]
    RedisMasterNode
        10
    RedisMasterNode  
       2020-05-17 00:00:52 +08:00
    1 楼正解,BloomFilter 处理超大数据量天然优势
    qbmiller
        11
    qbmiller  
       2020-05-17 00:14:01 +08:00 via iPhone
    布隆过滤 ,判断重复是有误判的。2000 万 数据库 sql 就可以了。太看不起 mysql 了。如果是阿里云 rds,那更完美
    qwertyegg
        12
    qwertyegg  
       2020-05-17 08:40:50 +08:00
    两千万小 case 了,每个记录算一个 hash 即可
    xcstream
        13
    xcstream  
       2020-05-17 10:32:23 +08:00
    32bit 换成 64bit 不知道行不行,不用改代码
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1109 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 19:42 · PVG 03:42 · LAX 11:42 · JFK 14:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.