2011-09-08 87 views
38

我不得不聚类numpy数组中的连续元素。考虑下面的例子如何从numpy数组中找到连续元素的组?

a = [ 0, 47, 48, 49, 50, 97, 98, 99] 

输出应元组的列表如下所示

[(0),(47, 48, 49, 50),(97, 98, 99)] 

不同的是只有一个。元素之间。如果差异也可以指定为限制或硬编码数字,那将是非常好的。

非常感谢。

+0

我发现这个答案有完全相同的问题...小世界! :o) – heltonbiker

+0

[识别列表中的连续号码组]可能的重复(http://stackoverflow.com/questions/2154249/identify-groups-of-continuous-numbers-in-a-list) – styvane

+0

另请参阅: https://stupidpythonideas.blogspot.com/2014/01/grouping-into-runs-of-adjacent-values.html – ShreevatsaR

回答

12

这里有一个可爱的FUNC,这可能有助于:

def group_consecutives(vals, step=1): 
    """Return list of consecutive lists of numbers from vals (number list).""" 
    run = [] 
    result = [run] 
    expect = None 
    for v in vals: 
     if (v == expect) or (expect is None): 
      run.append(v) 
     else: 
      run = [v] 
      result.append(run) 
     expect = v + step 
    return result 

>>> group_consecutives(a) 
[[0], [47, 48, 49, 50], [97, 98, 99]] 
>>> group_consecutives(a, step=47) 
[[0, 47], [48], [49], [50, 97], [98], [99]] 
+2

P.S.如果你想要元组而不是列表,你可以做'tuple(map(tuple,group_consecutives(a)))' – dkamins

+0

感谢这完全符合我的需求! – Shan

+3

这不是一个NumPy解决方案! – marscher

0

这听起来有点像功课,所以如果你不介意,我会建议使用

for i in range(len(a)): 
    print a[i] 

在列表中遇到一些你可以测试下一个元素的方法

可以遍历一个列表标准如下喜欢

if a[i] == a[i] + 1: 
    print "it must be a consecutive run" 

而且你可以在

seperately存储结果
results = [] 

当心 - 有一个索引超出范围的错误隐藏在上面,你将需要处理

+2

当存在更明显的解决方案时,请不要建议在numpy数组上使用python迭代器。它打败了使用numpy的目的。 (通常)。如果OP不关心性能,他们可能会使用python列表。 – Paul

6

(a[1:]-a[:-1])==1将产生一个布尔数组,其中False表示在运行中断的。您也可以使用内置的numpy.grad

+0

很酷的解决方案1up – Shan

+0

我不明白这个答案,虽然它是唯一一个看起来“功能性”(如在功能语言中)。你在这里做的是将减号运算符应用于列表。我不明白这是如何工作的。 –

+2

@LukeSkywalker它不起作用。在这种情况下,'a'是一个numpy数组,不是一个列表,减号运算符是按照元素进行减法。 – Paul

4

这就是我想出迄今:不知道是100%正确的

import numpy as np 
a = np.array([ 0, 47, 48, 49, 50, 97, 98, 99]) 
print np.split(a, np.cumsum(np.where(a[1:] - a[:-1] > 1))+1) 

回报:

>>>[array([0]), array([47, 48, 49, 50]), array([97, 98, 99])] 
+0

cool solution 1 up – Shan

+1

计数器示例:a = np.array([0,47,48,49,50,97,98,99,101,102,103,140,​​141])print(np.split(a ,np.cumsum(np.where(a [1:] - a [: - 1]> 1))+1))生成[array([0]),array([47,48,49,50]) ,array([97,98,99,101,102,103,140]),array([141]),array([],dtype = int64)] – Back2Basics

100
def consecutive(data, stepsize=1): 
    return np.split(data, np.where(np.diff(data) != stepsize)[0]+1) 

a = np.array([0, 47, 48, 49, 50, 97, 98, 99]) 
consecutive(a) 

收益率

[array([0]), array([47, 48, 49, 50]), array([97, 98, 99])] 
+1

我没有意识到'array_split'存在!这非常方便!谢谢! –

+2

很酷的解决方案1 ​​up – Shan

+1

并找到相同字符串的运行:'partitions = np.where(a [1:]!= a [: - 1])[0] + 1'('np.diff'不为字符串工作) – z0r

相关问题