2016-04-15 12 views
3

2つのサブグループに重複する日付があるかどうかを確認する大規模なgroupbyクエリで関数を実行する必要があります。以下は、単一のグループtmpの例である:パンダは複数の行で日付が重複しているかどうかを確認します

ID num start  stop  subGroup 
0 21 10 2006-10-10 2008-10-03 1 
1 21 46 2006-10-10 2100-01-01 2 
2 21 5 1997-11-25 1998-09-29 1 
3 21 42 1998-09-29 2100-01-01 2 
4 21 3 1997-01-07 1997-11-25 1 
5 21 6 2006-10-10 2008-10-03 1 
6 21 47 1998-09-29 2006-10-10 2 
7 21 4 1997-01-07 1998-09-29 1 

私はこれを行うために書いた関数は次のようになります。問題は、このコードは、多くの冗長性を持っていると私は、クエリを実行するとことをされて

def hasOverlap(tmp): 
    d2_starts = tmp[tmp['subGroup']==2]['start'] 
    d2_stops = tmp[tmp['subGroup']==2]['stop'] 
    return tmp[tmp['subGroup']==1].apply(lambda row_d1: 
     (
      #Check for part nested D2 in D1 
      ((d2_starts >= row_d1['start']) & 
      (d2_starts < row_d1['stop'])) | 
      ((d2_stops >= row_d1['start']) & 
      (d2_stops < row_d1['stop'])) | 
      #Check for fully nested D1 in D2 
      ((d2_stops >= row_d1['stop']) & 
      (d2_starts <= row_d1['start'])) 
     ).any() 
     ,axis = 1 
     ).any() 

groups.agg(hasOverlap) 

終了するには非常に時間がかかります。

これをスピードアップするためのパフォーマンスの修正(組み込み関数やset_indexの使用など)はありますか?

+0

あなたは、文字列または日時のオブジェクトを比較しています:Dをあなたはこのような何かを試みることができる

? – Mai

+0

日時オブジェクト:) – TimY

+0

datetimeをunixタイムスタンプにキャストし、minを減算してから、 '.astype(np.int32)'が役立つでしょうか? – Mai

答えて

0

オーバーラップの有無に基づいて「真」または「偽」を返すだけでいいですか?もしそうなら、私はちょうど各サブグループの日付のリストを取得し、それらが重複するかどうかを確認するためにパンダisinメソッドを使用します。

#split subgroups into separate DF's 
group1 = groups[groups.subgroup==1] 
group2 = groups[groups.subgroup==2] 

#check if any of the start dates from group 2 are in group 1 
if len(group1[group1.start.isin(list(group2.start))]) >0: 
    print "Group1 overlaps group2" 

#check if any of the start dates from group 1 are in group 2 
if len(group2[group2.start.isin(list(group1.start))]) >0: 
    print "Group2 overlaps group1" 
関連する問題