2011-09-08 21 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

は役立つかもしれないlilの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" 

に続き、あなたは

で個別に結果を保存することができますように基準
results = [] 

は用心 - インデックスを使用すると、Falseは、実行中に休憩を示すboolean配列を生成します

+2

もっと明白な解決策が存在する場合は、numpy配列よりもPythonイテレータを使用することを推奨しないでください。それはnumpyを使う目的を打ち負かします。 (通常は。)OPがパフォーマンスに関心がなければ、おそらくPythonリストを使用していたでしょう。 – Paul

6

(a[1:]-a[:-1])==1に対処する必要があります上記に隠された範囲エラー外にあります。内蔵のnumpy.gradを使用することもできます。ここで

+0

クールな解決方法1up – Shan

+0

「機能的」(機能的言語のように見えます)の唯一の回答ですが、この回答は分かりません。あなたがここでやっていることは、マイナス演算子をリストに適用することです。私はそれがどのように働くのか見ていない。 –

+2

@LukeSkywalker機能しません。この場合の 'a'はリストではなく、数値的な配列であり、マイナス演算子は要素ごとの減算を行います。 – 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、 ([0])、配列([47,48,49,50])、np.cumsum(np.cn) ([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

そして、同じ文字列の実行を見つけるために: 'np.where(a [1:]!= a [: - 1])[0] + 1'(' np.diff'は文字列のための仕事) – z0r