2016-08-11 4 views
1

私は、駅識別コード( 'usaf')と日付で整理された天気観測(fzraHrObs)のデータフレームを持っています。 fzraHrObsにはいくつかの気象データ列があります。局コードと日付(DateTimeオブジェクト)のように見える:天気「イベント」はパンダの時差に基づいてグループ化されています

usaf  dat 
716270 2014-11-23 12:00:00 
      2015-12-20 08:00:00 
      2015-12-20 12:00:00 
716280 2015-12-19 08:00:00 
      2015-12-19 09:00:00 

私は観察が同じイベントで、以前の観測カウント後< 6時間を発生する局による「イベント」にこれらの観察グループにしたいです。次に、イベントの開始時間、終了時間、およびイベント数をデータフレームに出力します。上記の例のデータを考えると、私は、出力は次のようになりたいのですが:

usaf  eventNum start    end      count 
716270 1   2014-11-23 12:00:00 2014-11-23 12:00:00  1 
      2   2015-12-20 09:00:00 2015-12-20 12:00:00  2  
716280 1   2015-12-19 08:00:00 2015-12-19 09:00:00  2 

私は現在のために/ IFループとdictsでこれをやっているが、それはされていますので、パンダに物事を切り替えるに取り組んでいますはるかに効率的です。

私の最初の考えは、駅でグループ化された各行でdatのdiffを行い、それを数時間で得ることでした。したがって、私はこれを示す列 'diff'を持っています。私はイベントの開始/終了/継続時間を取得する方法を理解するのに苦労しています。私はfzraHrObs [fzraHrObs ['diff']> = 6]に関わるものも同様に関与するだろうと推測していますか?

+0

5時間間隔で3回観測した場合、3番目のイベントは同じイベントとしてカウントされます(前のイベントから6時間以内に発生したイベント)。または新しいイベントです(最初のイベントの6時間後)? – IanS

+0

良い質問です。はい - 3つ目のイベントは同じイベントとしてカウントされます。イベント内の各観測は、5時間以下で区切られます。 – MeteoMtl

答えて

2

あなたのコメントの答えは、以前のイベントだけを振り返る必要があるので、ループを避けることは簡単だということです。

df['new_event'] = df.groupby('usaf')['dat'].apply(lambda s: s.diff().dt.seconds > 6*3600) 

出力:

 usaf     dat new_event 
0 716270 2014-11-23 12:00:00  False 
1 716270 2015-12-20 08:00:00  True 
2 716270 2015-12-20 12:00:00  False 
3 716280 2015-12-19 08:00:00  False 
4 716280 2015-12-19 09:00:00  False 

True値でイベントカウントを増やし:

df['event'] = df.groupby('usaf')['new_event'].cumsum().astype('int') 

出力:イベントによって

 usaf     dat new_event event 
0 716270 2014-11-23 12:00:00  False  0 
1 716270 2015-12-20 08:00:00  True  1 
2 716270 2015-12-20 12:00:00  False  1 
3 716280 2015-12-19 08:00:00  False  0 
4 716280 2015-12-19 09:00:00  False  0 

グループ、およびaggを使用するために

df.groupby(['usaf', 'event'])['dat'].agg(['first', 'last', 'count']) 

出力::開始日と終了日を取得するためにfirstlastを含む複数の機能を、適用

      first    last count 
usaf event            
716270 0  2014-11-23 12:00:00 2014-11-23 12:00:00  1 
     1  2015-12-20 08:00:00 2015-12-20 12:00:00  2 
716280 0  2015-12-19 08:00:00 2015-12-19 09:00:00  2 

を行うために残されているすべてのインデックスをクリーンアップです!

+0

これは素晴らしいです - ありがとうございます!数日前にパンダを使い始めたばかりで、あなたの例はとても役に立ちます。 agg関数は私が取り組んでいるものにとって本当に便利です。 – MeteoMtl

+0

さらに洞察を得ることができるもう1つの質問 また、24時間未満で分割されたイベント、すなわち新しいイベントが前のイベントが終了した24時間後に開始する場所を別々に組み合わせたいとします。この場合、私は(start [idx] - end [idx-1])のようなものを見る必要があります。私はこれを行う最善の方法は、イベント#/ new_eventの列で元のfzraHrObs dfを使用することであろうと思われますか? – MeteoMtl

+1

実際にはこれを理解しました。現在の行と前の行の時間の差を使って列を作成しました。 fzraHrObs ['prev_dat'] = fzraHrObs ['dat'] groupby([fzraHrObs ['usaf']])shift(1) それらの違い。その後、その差が24時間未満かどうかを確認し、そうでなければnew_eventをfalseに設定しました。fzraHrObs.ix [fzraHrObs.timedif <24、 'new_event'] = False このコードブロックは上記のcumsumおよびagg行の前です。 – MeteoMtl

関連する問題