2017-10-19 20 views
2

私は2つの列でグループ分けしたいと思っています:user_idとdate;ただし、日付が十分に近い場合は、同じグループの2つのエントリの一部を考慮してグループ化することができるようにしたいと考えています。日付はm-d-yパンダグループ日付範囲

user_id  date  val 
1   1-1-17  1 
2   1-1-17  1 
3   1-1-17  1 
1   1-1-17  1 
1   1-2-17  1 
2   1-2-17  1 
2   1-10-17 1 
3   2-1-17  1 

グループはuser_idと+/- 3日間でグループ化されます。そうvalは次のようになります合計することによってグループ:誰かが、これは簡単に(多少)に行うことができることを考えることができ

user_id  date  sum(val) 
1   1-2-17  3 
2   1-2-17  2 
2   1-10-17 1 
3   1-1-17  1 
3   2-1-17  1 

任意の方法?私はそこにいくつか問題があることを知っています。たとえば、3日間の間隔で日付文字列が無限につながっている場合はどうすればよいでしょうか。使用している正確なデータには人あたり2つの値しかありません。

ありがとう!

答えて

5

私はdatetime列にこれを変換してから使用したいpd.TimeGrouper

dates = pd.to_datetime(df.date, format='%m-%d-%y') 
print(dates) 
0 2017-01-01 
1 2017-01-01 
2 2017-01-01 
3 2017-01-01 
4 2017-01-02 
5 2017-01-02 
6 2017-01-10 
7 2017-02-01 
Name: date, dtype: datetime64[ns] 

df = df.assign(date=dates).set_index('date')\ 
      .groupby(['user_id', pd.TimeGrouper('3D')]).sum().reset_index()  
print(df) 
    user_id  date val 
0  1 2017-01-01 3 
1  2 2017-01-01 2 
2  2 2017-01-10 1 
3  3 2017-01-01 1 
4  3 2017-01-31 1 

pd.Grouper使用

同様のソリューション:

df = df.assign(date=dates).groupby(['user_id', 
     pd.Grouper(key='date', freq='3D')]).sum().reset_index() 
print(df) 
    user_id  date val 
0  1 2017-01-01 3 
1  2 2017-01-01 2 
2  2 2017-01-10 1 
3  3 2017-01-01 1 
4  3 2017-01-31 1 

更新:TimeGrouperは、将来のバージョンで廃止される予定ですこのシナリオではGrouperが好ましいでしょう(ヘッドアップのおかげで、Vaishali!)。

+1

任意の時間に関連した質問に触れ、私はいつも恐れて... LOLところで+1 – Wen

+1

アメージング、決して使用ハタ何とか – Vaishali

+0

'Grouper' 'TimeGrouper'です。 – Wen

0

私は非常に醜いソリューションが付属していますが、まだ動作...

df=df.sort_values(['user_id','date']) 
df['Key']=df.sort_values(['user_id','date']).groupby('user_id')['date'].diff().dt.days.lt(3).ne(True).cumsum() 
df.groupby(['user_id','Key'],as_index=False).agg({'val':'sum','date':'first'}) 

Out[586]: 
    user_id Key val  date 
0  1 1 3 2017-01-01 
1  2 2 2 2017-01-01 
2  2 3 1 2017-01-10 
3  3 4 1 2017-01-01 
4  3 5 1 2017-02-01