2017-10-19 166 views
2

我期待分兩列:user_id和日期;但是,如果日期足夠接近,我希望能夠相應地考慮同一組和組中的兩個條目。日期是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 

任何人都可以想到,這可以做(有點)容易嗎?我知道這有一些有問題的方面。例如,如果日期在相隔三天的時間內連續不斷地連在一起,該怎麼辦。但確切的數據即時使用只有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