【问题标题】:Using Python & Regex, find duplicate lines使用 Python 和正则表达式,查找重复行
【发布时间】:2016-03-09 20:39:34
【问题描述】:

我被困在一个项目的某个部分,我需要消除一个 1.62 亿行长的文件中的重复行。我已经实现了以下脚本(但它并没有摆脱所有重复的行):

lines_seen = set() # holds lines already seen
outfile = open('C:\\Users\\Lucas\\Documents\\Python\\Pagelinks\\pagelinkSample_10K_cleaned11.txt', "w")
for line in open('C:\\Users\\Lucas\\Documents\\Python\\Pagelinks\\pagelinkSample_10K_cleaned10.txt', "r"):
    if line not in lines_seen: # not a duplicate
        outfile.write(line)
        lines_seen.add(line)
outfile.close()

我需要编写一个正则表达式来消除任何重复的行!任何帮助将不胜感激,谢谢!

编辑:我将 1.62 亿行插入 MS SQL 2014。使用批量插入时,它会通知我有重复条目作为错误消息。

也许它不起作用,因为我的方法将“看到”的行存储在内存中,然后继续扫描,最终因为文件太大而耗尽内存?

【问题讨论】:

  • 您确定您认为重复的行实际上是重复的吗?
  • 这段代码看起来很正确。查看recipeunique_everseen
  • 它们是否需要与原始文件的顺序相同?
  • 实际上set(至少在python中)已经使用hash来优化它们对内存的影响。 (根据我刚才使用unique.__sizeof__()sum(i.__sizeof__() for i in unique) 的测试)

标签: python regex


【解决方案1】:

如果您有一个包含 162M 行的文件,您可能不需要 Python。

您似乎在 Windows 上运行。如果你有 Linux / OSX / *BSD,或者安装了 Cygwin,你可以这样做:

cat the_huge_file | sort --unique > file_without_duplicates

在 Windows 上,有一个 sort shell 实用程序,所以

sort <the_huge_file >sorted_file 

应该可以工作,希望以节省内存的方式。也许它还有一个删除重复项的开关;咨询sort /?

如果没有,在排序后删除重复的行是小菜一碟:逐行读取文件(而不是一次读取整个文件),仅在与前一行不同时才使用一行。一个简单的 Python 程序就可以做到。

【讨论】:

  • 感谢您的帮助!然而,这是一个学校项目,教授要求我们使用 python 脚本来“清理”数据
  • 如果行是 40 个字符长,167M 行是 6.6 GB;可能比您可用的 RAM 更多。因此,您需要像编写sort 实用程序的大男孩一样:读取一定数量的行,使其适合内存,对它们进行排序并删除重复项,写入临时文件。阅读更多行,创建另一个临时文件等,直到所有源代码行都结束。然后开始合并这些文件(如果需要,可以随时创建其他临时文件),同时删除重复文件。合并需要 2 行 RAM 并减少文件数量;一旦你合并了最后两个文件,你就完成了。请参阅“合并排序”。
【解决方案2】:

这是使用 python 和 sqlite 的内存高效解决方案。该脚本将从文本文件中逐行读取并插入具有唯一索引的 sqlite。如果检测到重复,它将打印行号和行重复的内容。

最后,您将清理 sqlite 数据库中的数据。您可以轻松地将数据从 sqlite 导出到 cvs,甚至直接导出到 SqlServer。

import sqlite3

conn = sqlite3.connect('data.db')
with conn:
    file_name = 'C:\\Users\\Lucas\\Documents\\Python\\Pagelinks\\pagelinkSample_10K_cleaned10.txt'

    sql_create = "CREATE TABLE IF NOT EXISTS data(line TEXT UNIQUE)"
    sql_insert = "INSERT INTO data VALUES (?)"

    conn.execute(sql_create)
    conn.commit()

    index = 1

    with open(file_name, "r") as fp:
        for line in fp:
            p = line.strip()
            try:
                conn.execute(sql_insert, (p,))
            except sqlite3.IntegrityError:
                print('D: ' + str(index) + ':  ' + p)
            finally:
                index += 1
        conn.commit()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 2020-06-03
    • 2016-04-22
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    相关资源
    最近更新 更多