【问题标题】:Most Pythonic way to Cross-reference two lists交叉引用两个列表的大多数 Pythonic 方式
【发布时间】:2017-09-29 16:31:29
【问题描述】:

问题:

我需要在long 列表(约600,000 个条目)和short 列表(约300,000 个条目)之间执行一项有点复杂的交叉引用任务。我试图在两个列表之间找到相似的条目,每个唯一条目由三个不同的整数标识(称它们为int1int2int3)。基于一个列表中的三个整数标识符,我想查看这三个相同的整数是否在另一个列表中,并返回它们是哪些。

尝试

首先,我将long 列表中的每个三整数元组压缩到一个名为a 的数组中。同样,我将short 列表中的每个三整数元组压缩到一个名为b 的数组中:

a = [(int1,int2,int3),...] # 600,000 entries
b = [(int1,int2,int3),...] # 300,000 entries

然后我遍历a 中的每个条目以查看它是否在b 中。如果是,我将相应的元组附加到循环外的一个名为 c 的数组中:

c= []
for i in range(0,len(a),1):
    if a[i] in b:
        c.append(a[i])

迭代(毫不奇怪)非常慢。我猜 Python 必须在每次迭代时检查 b 是否为 a[i](约 300,000 次!),它的迭代次数为 600,000 次。现在已经用了一个多小时了,还没有完成,所以我知道我应该优化一些东西。

我的问题是:执行这种交叉引用的最 Pythonic 或最快的方法是什么?

【问题讨论】:

    标签: python arrays pandas numpy list-comprehension


    【解决方案1】:

    你可以使用集合:

    c = set(b).intersection(a)
    

    我选择将b 转换为一个集合,因为它是两个列表中较短的一个。使用intersection() 不需要先将列表a 转换为集合。

    您也可以这样做:

    c = set(a) & set(b)
    

    但是,这两个列表都需要先转换为set 类型。

    无论哪种方式,您都有一个 O(n) 操作,请参阅 time complexity

    【讨论】:

      【解决方案2】:

      Pandas解决方案:

      a = [(1,2,3),(4,5,6),(4,5,8),(1,2,8) ]
      b = [(1,2,3),(0,3,7),(4,5,8)]
      df1 = pd.DataFrame(a)
      print (df1)
         0  1  2
      0  1  2  3
      1  4  5  6
      2  4  5  8
      3  1  2  8
      
      df2 = pd.DataFrame(b)
      print (df2)
         0  1  2
      0  1  2  3
      1  0  3  7
      2  4  5  8
      
      df = pd.merge(df1, df2)
      print (df)
         0  1  2
      0  1  2  3
      1  4  5  8
      

      带有sets 的纯python 解决方案:

      c = list(set(b).intersection(set(a)))
      print (c)
      [(4, 5, 8), (1, 2, 3)]
      

      【讨论】:

        【解决方案3】:

        另一种有趣的方法:

        from itertools import compress
        list(compress(b, map(lambda x: x in a, b)))
        

        还有一个:

        filter(lambda x: x in a, b)
        

        【讨论】:

        • 您最好使用filter() 代替map() 并摆脱compress()x in a 仍然会很慢;考虑先将a 转换为集合。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-21
        • 1970-01-01
        相关资源
        最近更新 更多