假设我在一个numpy数组中有一堆数字,我根据返回布尔数组的条件测试它们:
np.random.seed(3456)
a = np.random.rand(8)
condition = a>0.5
使用这个布尔数组,我想计算连续出现的True的所有长度。例如,如果我有[True,True,True,False,False,True,True,False,True]
,我会想要回来[3,2,1]
。
我可以使用此代码执行此操作:
length,count = [],0
for i in range(len(condition)):
if condition[i]==True:
count += 1
elif condition[i]==False and count>0:
length.append(count)
count = 0
if i==len(condition)-1 and count>0:
length.append(count)
print length
但是这个或者python,numpy,scipy等函数是否已经实现了计算给定输入的列表或数组中连续出现的长度?
答案 0 :(得分:16)
如果你已经有一个numpy数组,这可能会更快:
>>> condition = np.array([True,True,True,False,False,True,True,False,True])
>>> np.diff(np.where(np.concatenate(([condition[0]],
condition[:-1] != condition[1:],
[True])))[0])[::2]
array([3, 2, 1])
它检测块开始的位置,具有第一个和最后一个块的逻辑,并简单地计算块开始之间的差异和丢弃与False
块相对应的长度。
答案 1 :(得分:13)
这是使用itertools
的解决方案(它可能不是最快的解决方案):
import itertools
condition = [True,True,True,False,False,True,True,False,True]
[ sum( 1 for _ in group ) for key, group in itertools.groupby( condition ) if key ]
Out:
[3, 2, 1]
答案 2 :(得分:0)
您还可以通过查看条件数组逆的索引(False
的结果)来计算连续的np.where
值之间的距离。技巧是确保布尔数组以False
开头。基本上,您是在计算True
条件之间的边界之间的距离。
condition = np.array([True, True, True, False, False, True, True, False, True, False])
if condition[0]:
condition = np.concatenate([[False], condition])
idx = np.where(~condition)[0]
最后一步,您需要从这些值中取1,以便同时删除左右边缘。
>>> np.ediff1d(idx) - 1
array([3, 0, 2, 1])