2017-10-19 2 views
2

Ich bin auf der Suche nach zwei Spalten gruppieren: Benutzer-ID und Datum; Wenn die Daten jedoch nah genug sind, möchte ich in der Lage sein, die beiden Einträge eines Teils derselben Gruppe und Gruppe entsprechend zu betrachten. Datum ist m-d-yPandas-Gruppe nach einem Datumsbereich

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 

Die Gruppierung würde Gruppe von user_id und Daten +/- 3 Tage voneinander. so dass die Gruppe durch Addition val aussehen würde:

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 

irgendeine Weise jemand denken konnte, dass diese leicht (etwas) getan werden könnte? Ich weiß, dass es einige problematische Aspekte gibt. Zum Beispiel, was zu tun ist, wenn die Daten endlos im Abstand von drei Tagen aneinanderreihen. aber die genauen Daten im verwenden hat nur 2 Werte pro Person.

Danke!

Antwort

5

Ich würde wandeln diese in eine datetime Spalte und verwenden Sie dann 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 

ähnliche Lösung mit 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 

Update: TimeGrouper wird in zukünftigen Versionen von veraltet Pandas, also Grouper wäre in diesem Szenario vorzuziehen (danke für den Kopf, Vaishali!).

+1

ich immer Angst, jederzeit im Zusammenhang Frage zu berühren ... LOL btw +1 – Wen

+1

Erstaunlich, nie verwendet Grouper irgendwie – Vaishali

+0

'Grouper' ist 'TimeGrouper' – Wen

0

ich mit einer sehr hässlichen Lösung komme aber immer noch arbeiten ...

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 
Verwandte Themen