Skip to main content
 首页 » 编程设计

python之如何在 Python 中有效地过滤重复行

2025年05月04日7sky-heaven

我的问题看起来很经典,但我在 stackoverflow 中找不到完全相同的问题。我希望我的问题不是重复的。

我有一个大文件。该文件有很多行和固定的列。我对所有列中的 A 列和 B 列感兴趣。目标是我想要获取行,其中 (1) 该行中 A 列中的值也出现在其他行中,并且 (2) 有不止一行与 A 列具有相同的值,但是B列的不同值。

考虑下表。我对第 1,3 和 5 行感兴趣,因为“a”出现在 3 行中,并且 B 列中的值不同。相比之下,我对第 2 行和第 4 行不感兴趣,因为“b”出现了两次,但它在 B 列中对应的值始终是“1”。同样,我对第 6 行不感兴趣,因为“c”只出现了一次。

# A B C D 
========= 
1 a 0 x x 
2 b 1 x x 
3 a 2 x x 
4 b 1 x x 
5 a 3 x x 
6 c 1 x x

To find such columns, I read all lines in the file, convert each line with an object, create list for the objects, and find interesting columns with the following algorithm. The algorithm works, but takes time for my dataset. Do you have any suggestions to make the algorithm efficient?

def getDuplicateList(oldlist): 
    # find duplicate elements 
    duplicate = set() 
    a_to_b = {} 
    for elements in oldlist: 
        a = elements.getA() 
        b = elements.getB() 
        if a in a_to_b: 
            if b != a_to_b[a]: 
                duplicate.add(a) 
        a_to_b[a] = b  
 
    # get duplicate list 
    newlist = [] 
    for elements in oldlist: 
        a = elements.getA() 
        if a in duplicate: 
            newlist.append(a) 
 
    return newlist

附注我添加了一些限制条件来澄清。

  1. 我正在使用 Python 2.7
  2. 我需要“所有有趣的行”:duplicate 有“一些”有趣的“a”。
  3. 顺序很重要
  4. 实际上,数据是程序执行的内存访问。 A 列有内存访问,B 列有一些我感兴趣的条件。如果内存访问在运行时有多个条件,那么我想调查内存访问的顺序。

请您参考如下方法:

好吧,oldlist 中元素的两次迭代可以用一次迭代代替。我相信在大多数情况下,这会提高算法的效率,尤其是对于长列表。

如果 newlist 的顺序对您来说无关紧要,我建议使用与您的算法具有相同结果的单循环替换。我已经针对随机生成的百万元素列表对其进行了测试,它总是在大约一半的时间内运行:

def new_getDuplicateList(oldlist): 
    # find duplicate elements 
    newlist = [] 
    duplicate = set() 
    a_to_b = {} 
    for elements in oldlist: 
        a = elements[0] 
        b = elements[1] 
        if a in duplicate: 
            newlist.append(a) 
        else: 
            if a in a_to_b.keys(): 
                if not b in a_to_b[a]: 
                    a_to_b[a].append(b) 
                    duplicate.add(a) 
                    extension = [a for i in a_to_b[a]] 
                    newlist.extend(extension) 
                else: 
                    a_to_b[a].append(b) 
            else: 
                a_to_b[a] = [b] 
 
    return newlist 

(可能条件可以做得更漂亮。)修改它以输出整行而不只是 a 值会很容易,只需替换 a必要时通过(a, b)。另请注意,由于 a_to_b 字典现在包含列表,因此它比第一个算法消耗更多的内存。