如何在Python中对相同布尔值的块进行分组

时间:2018-11-12 16:00:19

标签: python numpy itertools

假设我有以下列表:

a = [True, True, True, False, False, False, False, True, True]

如何只返回037或类似的分组来使它们最好地分组

[True, True, True]
[False, False, False, False]
[True, True]

背景:我正在尝试在numpy数组中找到平稳状态,虽然将导数设置为零是一个不错的开始,但我仍然需要将数组按块排序。我认为这基本上可以归结为上述问题。我查找了numpy和itertools(试图从问题Numpy grouping using itertools.groupby performance中获取解决方案),但没有成功。我猜可能会使用itertools.takewhile和filtfalse的组合(请参阅doc here),但是我不尽如人意。也许我只是想办法变得复杂。

3 个答案:

答案 0 :(得分:3)

我们可以通过切片数组比较来获取索引,并且在大型列表/数组的情况下应该表现出色-

command.ExecuteNonQuery();

作为单行代码,我们可以使用a_ext = np.r_[~a[0],a] out = np.flatnonzero(a_ext[:-1]!=a_ext[1:]) + np.diff-

np.flatnonzero

答案 1 :(得分:2)

最简单的方法可能是这样:

a = [True, True, True, False, False, False, False, True, True]

res = [0] + [i+1 for i, (x, y) in enumerate(zip(a, a[1:])) if x!=y]
print(res)  # -> [0, 3, 7]

groupby解决方案而言,您可以执行以下操作:

from itertools import groupby

groups = [list(g) for _, g in groupby(a)]
print(groups)  # -> [[True, True, True], [False, False, False, False], [True, True]]

答案 2 :(得分:1)

您可以使用itertools.groupby完全做到这一点:

给出

import itertools as it


a = [True, True, True, False, False, False, False, True, True]

代码

[list(g)[0][0] for _, g in it.groupby(enumerate(a), key=lambda x: x[-1])]
# [0, 3, 7]

详细信息

这是groupby的迭代输出:

[(k, list(g)) for k, g in it.groupby(a)]
# [(True, [True, True, True]),
#  (False, [False, False, False, False]),
#  (True, [True, True])]

我们可以将每个组(g)中的每个项目枚举为元组,并按每个元组中的最后一个索引进行分组:

[list(g) for k, g in it.groupby(enumerate(a), key=lambda x: x[-1])]
# [[(0, True), (1, True), (2, True)],
#  [(3, False), (4, False), (5, False), (6, False)],
#  [(7, True), (8, True)]]

现在,我们希望第一项([0])和第一位置([0])获得每个组的索引。

@Chris_Rands对[next(g)[0] ...]的建议更加清晰。

另请参见this post,以了解如何使用groupby