2017-08-23 17 views
3

との差に基づいて、アレイの行を結合し、Iが与えられてい言う(N、2)のために、セグメントの開始と終了指標の一連の記録numpyのアレイ例n = 6:パイソン:前の行の最後の要素と後部行の最初の要素タイトルとして

import numpy as np 
# x records the (start, end) index pairs corresponding to six segments 
x = np.array(([0,4], # the 1st seg ranges from index 0 ~ 4 
       [5,9], # the 2nd seg ranges from index 5 ~ 9, etc. 
       [10,13], 
       [15,20], 
       [23,30], 
       [31,40])) 

ここでは、これらのセグメントを小さな間隔で結合したいと考えています。たとえば、間隔が1より大きい全くない場合の連続セグメントをマージし、所望の出力は次のようになります

y = np.array([0,13], # Cuz the 1st seg's end is close to 2nd's start, 
         # and 2nd seg's end is close to 3rd's start, so are combined. 
      [15,20], # The 4th seg is away from the prior and posterior segs, 
         # so it remains untouched. 
      [23,40]) # The 5th and 6th segs are close, so are combined 

出力セグメントはわずか3の代わりに6であることが判明するであろうように。 何か提案がありがとうございます!

+0

あなたは 'numpy'ソリューションをしたいか、どんな解決策がokですか? –

+0

'numpy'はとにかく好きです:) – Francis

+0

@Thomasしかし、numpy以外の方法は素晴らしいでしょう – Francis

答えて

2

セグメントが順序付けされていると仮定でき、ネイバー内に完全に含まれていないと仮定すると、ある範囲の終了値と次の開始点の間のギャップが条件を満たす箇所:

start = x[1:, 0] # select columns, ignoring the beginning of the first range 
end = x[:-1, 1] # and the end of the final range 
mask = start>end+1 # identify where consecutive rows have too great a gap 

はその後戻って一緒にこれらの作品をステッチ:

np.array([np.insert(start[mask], 0, x[0, 0]), np.append(end[mask], x[-1, -1])]).T 
Out[96]: 
array([[ 0, 13], 
     [15, 20], 
     [23, 40]]) 
2

ここでnumpyのベクトル化されたソリューションです -

def merge_boundaries(x): 
    mask = (x[1:,0] - x[:-1,1])!=1 
    idx = np.flatnonzero(mask) 
    start = np.r_[0,idx+1] 
    stop = np.r_[idx, x.shape[0]-1] 
    return np.c_[x[start,0], x[stop,1]] 

サンプル実行 -

In [230]: x 
Out[230]: 
array([[ 0, 4], 
     [ 5, 9], 
     [10, 13], 
     [15, 20], 
     [23, 30], 
     [31, 40]]) 

In [231]: merge_boundaries(x) 
Out[231]: 
array([[ 0, 13], 
     [15, 20], 
     [23, 40]]) 
関連する問題