对 python 列表中的连续项目对进行排序



我拥有的数据实际上包含在pandas数据帧中(在列上(,但为了这篇文章,我们提取它以解决问题的核心。

假设我们有一个数据帧df,其中包含一列col1,我们将其存储为列表:L = df.col1.tolist()。现在,我有大约 2000 个这样的列/列表,平均它们的长度约为 300-400。因此,这里对性能的需求并不大。

回到我们的 MWE 列表,它的结构如下(ish(:

L = [1,2,2,1,3,3,4,4,5,5,6,6,1,2,1,2,7,7,8,8]

现在,列表中的项目的结构方式应该是连续对(但出于数据收集原因,它们不是(。因此,这是我们的目标排序列表:

L = [1,1,2,2,3,3,4,4,5,5,6,6,1,1,2,2,7,7,8,8]

为了清楚起见,我将这些添加为元组:

L = [(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(1,1),(2,2),(7,7),(8,8)]

这就是问题所在:列包含几乎连续的项目对(上面示例中的数字(,但其中一些是无序的,必须移回它们的伙伴(见上文(。

需要注意的几点:

  • 上面的列表包含数字,实际上,我们正在处理字符串
  • 数据通常位于 pandas 数据帧中的列上(不确定这是否有帮助,但可能会(
  • 性能不是真正的问题,因为它们只需要排序一次
  • 乱序模式不一致,每列中的东西移动很多,重要的是每个项目都映射回其伙伴。

我正在寻找一种可以将这些列表/列按所需的对顺序排序的方法。谢谢!

好的,因为您可以保证它们始终是配对的,所以我只保留一个运行计数,您基本上只需要按照遇到对中第一项的顺序生成元素列表(因此当计数等于零时(,当计数达到 2 时,重置该项目的计数。然后只需将第一个元素列表按顺序"分解"成对列表,如此快速和肮脏:

In [1]: L = [1,2,2,1,3,3,4,4,5,5,6,6,1,2,1,2,7,7,8,8]
In [2]: from collections import Counter
In [3]: counts = Counter()
In [4]: order = []
In [5]: for x in L:
...:     n = counts[x]
...:     if n == 0:
...:         order.append(x)
...:         counts[x] += 1
...:     elif n == 2:
...:         counts[x] = 0
...:     else:
...:         counts[x] += 1
...:
In [6]: order
Out[6]: [1, 2, 3, 4, 5, 6, 1, 2, 7, 8]
In [7]: result = []
In [8]: for x in order:
...:     result.append(x)
...:     result.append(x)
...:
In [9]: result
Out[9]: [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 1, 1, 2, 2, 7, 7, 8, 8]

当然,你应该创建一个函数来做到这一点。

最新更新