【问题标题】:Removing duplicate interaction pairs in python sets删除python集中重复的交互对
【发布时间】:2012-03-19 03:16:40
【问题描述】:

假设你有一个 python 集中的元组列表:

>>> pairs = set( [(0,1),(0,1),(1,0)] )
>>> print pairs
set([(0, 1), (1, 0)])

显然,前两个元素是重复的,并且根据 对于集合的定义,“pairs”只包含唯一元素。

但是,在我的特殊情况下,元组 (i,j) 定义了一个交互对。因此, (i,j) 和 (j,i) 相同。我需要一种有效的方法来减少所有重复 元素。计算时间对我来说至关重要,因为整个集合很容易包含许多 10**6 的元素。我希望得到以下结果:

>>> pairs = set( [(0,1),(0,1),(1,0)] )
>>> pairs = remove_duplicate_interactions(pairs)
>>> print pairs
set([0,1]) or set([1,0])

感谢任何提示。

编辑:

有人询问上下文。这应该用于粒子模拟。 由于对称条件,粒子 i 作用于 j 的力与 j 作用于 i 的力相同。因此计算时间减少了 50 %。

【问题讨论】:

  • 没有任何维度的排序。集合([(i,j),(k,l),..]) = 集合([ (k,l),(i,j),..]) = 集合([(j,i),( l,k),...]) ...

标签: python set tuples


【解决方案1】:

怎么样:

In [4]: pairs = set( [(0,1),(0,1),(1,0),(1,2),(1,0),(2,1)] )

In [5]: set((a,b) if a<=b else (b,a) for a,b in pairs)
Out[5]: set([(0, 1), (1, 2)])

【讨论】:

  • 你们怎么可能总是找到单线解决方案?
  • @RakulanS.:设计更难的问题 :)
【解决方案2】:
pairs = set(frozenset(p) for p in ((0,1),(0,1),(1,0)) )

将实现您所需要的。请在此处查看我的答案以获取更多信息:How do I perform deep equality comparisons of two lists of tuples?

如有必要,您可以在之后将它们重新组合成对。

【讨论】:

    【解决方案3】:
    >>> pairs = [(0,1),(0,1),(1,0)]
    >>> set(tuple(sorted(p)) for p in pairs)
    set([(0, 1)])
    

    【讨论】:

    • 非常有帮助
    【解决方案4】:

    我将子类型 tuple 并始终使这对有序:

    class InteractionPair(tuple):
        def __new__(cls, a, b):
            if a <= b:
                return tuple.__new__(cls, (a, b))
            return tuple.__new__(cls, (b, a))
    

    例子:

    >>> set([InteractionPair(0, 1), InteractionPair(1, 0)])
    set([(0, 1)])
    

    这也可以应用于标准元组列表:

    from itertools import starmap
    pairs = [(0, 1), (0, 1), (1, 0)]
    print set(starmap(InteractionPair, pairs))
    

    编辑:她是一些时间,使用 1000000 个随机对的列表:

    In [14]: timeit set(starmap(InteractionPair, pairs))
    1 loops, best of 3: 742 ms per loop
    
    In [15]: timeit set((a,b) if a<=b else (b,a) for a,b in pairs)
    1 loops, best of 3: 258 ms per loop
    
    In [16]: timeit set(tuple(sorted(p)) for p in pairs)
    1 loops, best of 3: 1.02 s per loop
    

    就性能而言,solution by aix 胜出。

    【讨论】:

    • @larsmans:不确定是不是真的。这种方法有时可能很有用,但您需要更多地了解上下文来判断这是否真的值得。
    • 我喜欢面向对象的方法,所以这对我来说也很优雅。但是效率呢?直觉上,这似乎计算量很大?!
    • @RakulanS.:添加了一些简单的计时。没那么糟糕。
    【解决方案5】:

    如果您可以使用frozenset 代替元组,则可以将每个交互对存储为一个集合。另一种方法是以某种规范形式存储所有元组(例如,i &lt; j)。不知道这是否比frozenset 有速度优势,但形式越简单,python 越快地散列它并计算唯一元素集。

    【讨论】:

      猜你喜欢
      • 2010-11-13
      • 2023-02-24
      • 1970-01-01
      • 2012-10-09
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      相关资源
      最近更新 更多