2017-05-17 1 views
1

日付セット間にギャップがあるかどうかを判断する必要があります(開始日と終了日によって決定されます)。データフレームaについてパンダを使用して日付に隙間があるかどうかを確認

import pandas as pd 

a = pd.DataFrame({'start_date' : ['01-01-2014', '01-01-2015', '05-01-2016'], 
      'end_date' : ['01-01-2015', '01-01-2016', '05-01-2017']}) 

order = ['start_date', 'end_date'] 

a = a[order] 

a.start_date = pd.to_datetime(a.start_date, dayfirst= True) 
a.end_date = pd.to_datetime(a.end_date, dayfirst= True) 


b = pd.DataFrame({'start_date' : ['01-01-2014', '01-01-2015', '05-01-2016', 
'05-01-2017', '01-01-2015'], 
      'end_date' : ['01-01-2015', '01-01-2016', '05-01-2017', 
          '05-01-2018', '05-01-2018']}) 

order = ['start_date', 'end_date'] 

b = b[order] 

b.start_date = pd.to_datetime(b.start_date, dayfirst= True) 
b.end_date = pd.to_datetime(b.end_date, dayfirst= True) 

a 
b 

、解決策が十分に単純です:私は2つの例のデータフレームを持っています。 start_dateで注文すると、end_dateが1つ下にずれて日付が差し引かれます。差が正であれば、日付に差があります。

しかし、これをデータフレームbに適用すると、より広い範囲を含む範囲があるため、あまり明確ではありません。私は間違ってギャップを見つけることはありませんこれを行う一般的な方法で不明です。これは、グループ化されたデータ(約40000グループ)に対して行われます。

答えて

1

あなたはこのような何か行うことができますIIUC:

In [198]: (b.sort_values('start_date') 
    ...: .stack() 
    ...: .shift().diff().dt.days 
    ...: .reset_index(name='days') 
    ...: .dropna() 
    ...: .query("level_1 == 'end_date' and days != 0")) 
    ...: 
Out[198]: 
    level_0 level_1 days 
5  4 end_date -365.0 
7  2 end_date -731.0 

次のコードは、私たちにギャップが発見されたインデックス表示される必要があります。

In [199]: (b.sort_values('start_date') 
    ...: .stack() 
    ...: .shift().diff().dt.days 
    ...: .reset_index(name='days') 
    ...: .dropna() 
    ...: .query("level_1 == 'end_date' and days != 0") 
    ...: .loc[:, 'level_0']) 
    ...: 
Out[199]: 
5 4 
7 2 
Name: level_0, dtype: int64 
+0

私はあなたがこれを削除したと思いました。まあ問題ありません:-) – piRSquared

+0

@ piRSquared、率直に言って私は覚えていません... ;-) – MaxU

1

をこれはアイデアです...

  • 開始日には+1、終了日には-1を割り当てます。
  • 私はすべての日付順に1つのフラットな配列として累積合計を取る。
  • 累積合計がゼロの場合、ギャップが発生します。
  • 日付の値が最初の優先順位で、その後にstart_dateが続きます。この方法では、ある行のend_dateが次の行の開始日と等しいときに、正の値を追加する前に負の値を追加しません。
  • 私は、物品を並べ替えて捻って回すのにnumpyを使用します。
  • returnギャップが始まるブールマスクです。

def find_gaps(b): 
    d1 = b.values.ravel() 
    d2 = np.tile([1, -1], len(d1) // 2) 
    s = np.lexsort([-d2, d1]) 
    u = np.empty_like(s) 
    r = np.arange(d1.size) 
    u[s] = r 
    return d2[s].cumsum()[u][1::2] == 0 

デモ

find_gaps(b) 

array([False, False, False, False, True], dtype=bool) 

find_gaps(a) 

array([False, True, True], dtype=bool) 
関連する問題