2017-05-31 1 views
2

私は以下のようなデータが含まれているデータフレーム(データの小さなサブセット)を持っている:日付範囲が重複している行を検索するにはどうすればよいですか?

enter image description here

私は私が持っているすべての行を含む新しいデータフレームを作成することができる方法を把握しようとしていますcarrier,flightnumber,departureAirportおよびarrivalAirportの同じ値が重複する日付範囲もあります。

はオーバーラップすることにより、私はeffectiveDateいずれかの行は、私が言及された他の列の同じ値を持つ別のレコードのeffectiveDatediscontinuedDate間に入る意味します。

私の上記の例では、最初の2行はこれの例とみなされます(また、両方とも新しいデータフレームに含める必要があります)が、3行目は含まれません。

私はgroupbyを使用したいと思っていますが、どの集約機能を適用するかは完全にはわかりません。以下は、私がこれまで持っているものです。

df.groupby(['carrier','flightnumber','departureAirport','arrivalAirport'])['effectiveDate', 'discontinuedDate'].min() 

が、明らかに私はmin()の代わりにオーバーラップするかを決定する関数を適用する必要があります。このグループの最小値を返すのではなく、どのようにオーバーラップを特定するのですか?

UPDATE:

carrier flightnumber departureAirport arrivalAirport effectiveDate discontinuedDate 
4U  9748   DUS    GVA    2017-05-09 2017-07-12 
4U  9748   DUS    GVA    2017-05-14 2017-07-16 
4U  9748   DUS    GVA    2017-07-18 2017-08-27 
AG  1234   SFO    DFW    2017-03-09 2017-05-12 
AG  1234   SFO    DFW    2017-03-14 2017-05-16 

はUPDATE 2:で返さ限り出力はIが重なるとcarrierに同じ値を持つ行をしたいのですが行くよう

flightnumberdepartureAirportarrivalAirport新しいデータフレームこれらの行には追加のデータを含める必要はありません。したがって、上記の例のデータのために、以下のようなデータフレームは、私の所望の出力のようになります。レコードは1つだけ(9748ための第三)は除外されていることを

carrier flightnumber departureAirport arrivalAirport effectiveDate discontinuedDate 
4U  9748   DUS    GVA    2017-05-09 2017-07-12 
4U  9748   DUS    GVA    2017-05-14 2017-07-16 
AG  1234   SFO    DFW    2017-03-09 2017-05-12 
AG  1234   SFO    DFW    2017-03-14 2017-05-16 

お知らせ - それは日付範囲だからこれは重複しません同じフライトの他の記録と比較します。

+0

は何をやりたいのですか?あるいは何かがこれらのシナリオを妨害していますか? – EFT

+0

複数の行が重なっている場合は、それらのすべてを返すことにします。いずれかの行が他の行と重なっている場合は、他の行との関係にかかわらず返すことにします。それは理にかなっていますか? –

+0

@piRSquared - sure。私は先に進んで、私の希望する出力に関する2番目のアップデートを追加しました。あなたがまだ周りにいる場合は、見て、それが明確にすることができれば私に知らせるために自由に感じる。乾杯。 –

答えて

2

ハイレベルコンセプト

  • 正確な重複がある場合effectiveDateを優先することにより、すべての日付と並べ替え。
  • 並べ替えの前に初期化された1つと1つを交互に合計します。要点は、累積合計が1を上回ったときにオーバーラップが発生することです。隣接グループは、合計が0に低下すると終了します。
  • 並べ替えをソートし、ゼロがどこで発生するかを特定します。これらはオーバーラップするグループの終わりです。
  • これらのブレークポイントでデータフレームインデックスを分割し、分割のサイズが1より大きい場合にのみ分割を行います。
  • 通過する分割を連結し、locを使用してスライスされたデータフレームを取得します。複数のサブグループが重なって、または2つの日付の範囲は第三ではなく、お互いに重複している場合

def overlaping_groups(df): 
    n = len(df) 
    cols = ['effectiveDate', 'discontinuedDate'] 
    v = np.column_stack([df[c].values for c in cols]).ravel() 
    i = np.tile([1, -1], n) 
    a = np.lexsort([-i, v]) 
    u = np.empty_like(a) 
    u[a] = np.arange(a.size) 
    e = np.flatnonzero(i[a].cumsum()[u][1::2] == 0) 
    d = np.diff(np.append(-1, e)) 
    s = np.split(df.index.values, e[:-1] + 1) 

    return df.loc[np.concatenate([g for j, g in enumerate(s) if d[j] > 1])] 

gcols = ['carrier', 'flightnumber', 'departureAirport', 'arrivalAirport'] 
df.groupby(gcols, group_keys=False).apply(overlaping_groups) 

    carrier flightnumber departureAirport arrivalAirport effectiveDate discontinuedDate 
0  4U   9748    DUS   GVA 2017-05-09  2017-07-12 
1  4U   9748    DUS   GVA 2017-05-14  2017-07-16 
3  AG   1234    SFO   DFW 2017-03-09  2017-05-12 
4  AG   1234    SFO   DFW 2017-03-14  2017-05-16 
関連する問題