2016-10-29 5 views
1

Probleme beim Berechnen rollender 7-Tage-Unique User nach Gruppe in einem Group-User-Date-Dataset. Es ist eine klassische Metrik, und mir ist klar, dass mir jemand bei Pandas helfen könnte.rolling uniques über Gruppen + Zeit in Pandas

Beispieldaten:

from StringIO import StringIO 
import pandas as pd 

data = StringIO("""grp1,user,date 
    a,1,2016-10-10 
    a,1,2016-10-09 
    a,1,2016-10-07 
    a,2,2016-10-09 
    a,2,2016-10-06 
    a,3,2016-10-10 
    a,3,2016-10-09 
    """) 

df = pd.read_csv(data) 

Für diesen einfachen Datensatz möchte ich zurück:

a, 2016-10-10, 3 <- 3 users were in group a in the 7 days ending 10/10 
    a, 2016-10-09, 3 <- 3 users were in group a in the 7 days ending 10/09 
    a, 2016-10-07, 2 <- 2 users were in group a in the 7 days ending 10/07 
    a, 2016-10-06, 1 <- 1 users were in group a in the 7 days ending 10/06 

ich nichts dagegen, wenn es sich um eine des ursprünglichen Datensatzes oder einer Aggregation Transformation ist.

haben 1) eine Menge Such versucht und 2) eine Menge von Variationen von

from datetime import datetime, timedelta 

rolling_uniques = lambda x: x['user'].unique().size if x['date'] + timedelta(days=6) <= x['date'].max() else 0 

df.apply(rolling_uniques, axis=1) 

ODER

df.groupby(['grp1', 'user', 'date']).transform(rolling_uniques) 

aber nichts arbeitet aus. In meinen Daten habe ich mehrere Gruppenspalten und natürlich mehr Kategorien innerhalb von grp1 als nur 'a'.

+0

Haben Sie sich die df.rolling Funktion angesehen? – Boud

+0

ja, spielte mit dem ein Bündel, aber scheint passen Sum/Anzahl/etc Anwendungsfälle, aber nicht in willkürlichen Gruppen Uniques –

+0

bis jetzt der einzige Ansatz, den ich arbeiten kann, ist durch die Gruppen zu durchlaufen, durchlaufen die Daten und berechnen die eindeutigen Benutzer für die Zeilen innerhalb von 7 Tagen –

Antwort

1

Ich nicht jetzt, wenn es genau das erwartete Ergebnis ist, aber ich denke, dass es Ihnen helfen kann. Gib mir Bescheid.

# Test data 
data = io.StringIO("""grp1,user,date 
    a,1,2016-10-10 
    a,1,2016-10-09 
    a,1,2016-10-07 
    a,2,2016-10-09 
    a,2,2016-10-06 
    a,3,2016-10-10 
    a,3,2016-10-09 
    b,1,2016-10-09 
    b,2,2016-10-10 
    """) 


df = pd.read_csv(data) 
df['date'] = pd.to_datetime(df['date']) 
# Setting and sorting the index 
df.set_index('date', inplace=True) 
df.sort_index(inplace=True) 

# Resampling data by preserving the group 
df = df.groupby([df.index.to_period('D'), df['grp1']]).sum() 
df = df.unstack('grp1') 
df = df.resample('D').sum().fillna(0) 
# Computing the rolling sum 
df = df.rolling(7, min_periods=0).sum() 

# Formatting 
df = df.stack() 
df = df.swaplevel(0,1) 

print(df) 
#     user 
# grp1 date    
#  a 2016-10-06 2.0 
#  b 2016-10-06 0.0 
#  a 2016-10-07 3.0 
#  b 2016-10-07 0.0 
#  a 2016-10-08 3.0 
#  b 2016-10-08 0.0 
#  a 2016-10-09 9.0 
#  b 2016-10-09 1.0 
#  a 2016-10-10 13.0 
#  b 2016-10-10 3.0 
+0

danke für die Antwort. hat den Code ausgeführt, sieht so aus, als würde er die Benutzerspalte summieren, anstatt uniques über die vorherigen Daten zu erhalten. die resample kann helfen –