Python 计数numpy数组中长度不同的值的连续出现次数
假设我在一个numpy数组中有一组数字,我根据返回布尔数组的条件对它们进行测试:Python 计数numpy数组中长度不同的值的连续出现次数,python,arrays,numpy,Python,Arrays,Numpy,假设我在一个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 ra
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等函数实现了任何计算给定输入的列表或数组中连续出现的长度的功能?这里有一个使用
itertools
的解决方案(这可能不是最快的解决方案):
如果您已经有一个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
块。您还可以通过查看索引来计算连续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])
可能是重复的,谢谢你指出这一点。我永远也不会发现这是一个非常好的答案!实际上,这比我上面的代码截取要快得多。与~1-2相比,大约0.2秒它起作用了。。。但随后它开始向我显示这个错误:
包含多个元素的数组的真值是不明确的
。出乎意料,不知道为什么。它在空闲状态下工作,byt不在PyCharm中。如果使用len(list(group))而不是sum(1…),它会稍微快一点,但是如果你已经有一个numpy数组,它仍然比@Jaime的答案慢很多。我将这个函数传递给grouby,并对pandas数据帧上的方法进行重新采样,所以我猜它最终将是一个numpy数组。在这种情况下,速度不是什么大问题,但在数据集大得多的情况下,我发现1e6 bools的速度比itertools方法快几个数量级。谢谢很好,谢谢!您是否有建议如何修改您的代码,以便在2D numpy数组上按行执行此操作?@pr94按行执行可能会为每个答案提供不同长度的数组。我猜您必须一次只做一行,因此您只需要以某种方式循环它,并添加额外的索引[0,:]
,而不是[0]
>>> np.ediff1d(idx) - 1
array([3, 0, 2, 1])