从巨大的文件中删除重复项

时间:2012-04-28 05:54:45

标签: algorithm file-io large-files

我们有大量数据,我们希望对它们执行一些操作。删除重复项是主要操作之一。

实施例

a,me,123,2631272164
yrw,wq,1237,123712,126128361
yrw,dsfswq,1323237,12xcvcx3712,1sd26128361

这是文件中的三个条目,我们希望在第一列的基础上删除重复项。因此,应删除第3行。每行可能有不同数量的列,但我们感兴趣的列将始终存在。

在内存操作中看起来不太可行。

另一个选择是将数据存储在数据库中并从那里删除重复项,但这又不是一项简单的任务。 我应该遵循什么设计来将数据转储到数据库中并删除重复数据?

我假设人们必须面对这些问题并解决它。

我们通常如何解决这个问题?

PS:请将此视为现实生活中的问题而不是面试问题;)

5 个答案:

答案 0 :(得分:4)

如果加载到内存中的键数也不可行,则必须执行稳定(保留顺序)外部合并排序以对数据进行排序,然后进行线性扫描以执行重复删除。或者,您可以修改外部合并排序,以便在合并已排序的运行时提供重复消除。

我想因为这不是面试问题或效率/优雅似乎不是问题(?)。编写一个hack python脚本,创建1个表,第一个字段作为主键。解析此文件并将记录插入数据库,将插入包装到try except语句中。然后在表格上执行select *,解析数据并逐行将其写回文件。

答案 1 :(得分:1)

如果沿着数据库路线走下去,可以将csv加载到数据库中并使用“重复密钥更新”

使用mysql: -

  1. 创建一个包含行以匹配您的数据的表(您可能只能使用2行 - id和数据)
  2. 使用

    行中的内容转储数据

    LOAD DATA LOCAL infile“rs.txt”REPLACE INTO TABLE data_table FIELDS TERMINATED by',';

  3. 然后,您应该能够将数据转储回csv格式而不会重复。

答案 2 :(得分:0)

如果输入已排序或可以排序,那么可以执行此操作,只需要在内存中存储一​​个值:

r = read_row()
if r is None:
    os.exit()
last = r[0]
write_row(r)
while True:
    r = read_row()
    if r is None:
        os.exit()
    if r[0] != last:
        write_row(r)
        last = r[0]

否则:

我要做的是保留一组我已经看过的第一列值,如果它在该集合中,则删除该行。

S = set()
while True:
    r = read_row()
    if r is None:
       os.exit()
    if r[0] not in S:
       write_row(r)
       S.add(r[0])

这将仅使用与第一列中的值集大小成比例的内存来输入输入。

答案 3 :(得分:0)

如果唯一键的数量不是很高,你可以简单地执行此操作;
(伪代码,因为你没有提到语言)

Set keySet;

while(not end_of_input_file)
    read line from input file
    if first column is not in keySet
        add first column to keySet
        write line to output file
end while

答案 4 :(得分:0)

如果您需要保留原始数据的顺序,创建位置和数据元组的新数据,然后对要删除的数据进行排序可能是明智的。按数据排序后,重复数据删除(基本上)是线性扫描。之后,您可以通过对元组的位置部分进行排序,然后将其剥离来重新创建原始订单。

假设您有以下数据:a,c,a,b

使用按数据排序的pos / data元组,我们得到:0 / a,2 / a,3 / b,1 / c

然后我们可以去重复,平凡地能够选择要保留的第一个或最后一个条目(我们也可以,更多的内存消耗,保留另一个)并得到:0 / a,3 / b,1 / C

然后我们按位置排序并剥离:a,c,b

这将涉及对数据集的三次线性扫描和两个排序步骤。