Calculate Distinct Count in rolling 3 Days Pandas?

Viewed 143

I want to count unique customers over 3 days window grouped by city

input:

    df = pd.DataFrame([['1A', 'Cairo', '2020-12-01'],
                ["2A", 'Cairo', '2020-12-01'],
                ['1A', 'Cairo', '2020-12-02'],
                ['1A', 'Cairo', '2020-12-03'],
                ['3A', 'Alex', '2020-12-01'],
                ['3A', 'Alex', '2020-12-02'],
                ['3A', 'Alex', '2020-12-03'],
                ['4A', 'Giza', '2020-12-02'],
                ['4A', 'Giza', '2020-12-02'],
                ['5A', 'Giza', '2020-12-03'],
                ['6A', 'Giza', '2020-12-01']], columns=
    ['customer_id', 'city', 'day'])

expected output :

    output = pd.DataFrame([['Alex', '2020-12-01',1],
                ['Alex', '2020-12-02',1],
                ['Alex', '2020-12-03',1],
                ['Cairo', '2020-12-01',2],
                ['Cairo', '2020-12-02',2],
                ['Cairo', '2020-12-03',2],
                ['Giza', '2020-12-01',1],
                ['Giza', '2020-12-02',2],
                ['Giza', '2020-12-03',3]], columns=
    ['city', 'day', 'unique_customers_last3Days'])

I tried:

df['day'] = pd.to_datetime(df['day'])
df.set_index('day',inplace=True)
df.sort_index(inplace=True)
df.groupby('city').rolling("3D").agg({'customer_id':'nun'})

but it gives me error

AttributeError: 'nunique' is not a valid function for 'RollingGroupby' object
1 Answers

Set the index of dataframe to day then sort the index values, now factorize the customer_id column in order to assign unique codes to each of the customer id, then group the dataframe on city and apply a rolling nunique operation with window size of 3 days. Optionally drop the duplicate values in day for each city

df = df.set_index('day').sort_index()
df['codes'] = df['customer_id'].factorize()[0]

df.groupby('city')\
  .rolling('3D')['codes'].apply(pd.Series.nunique)\
  .reset_index(name='unique').drop_duplicates(['city', 'day'], keep='last')

     city        day  unique
0    Alex 2020-12-01     1.0
1    Alex 2020-12-02     1.0
2    Alex 2020-12-03     1.0
4   Cairo 2020-12-01     2.0
5   Cairo 2020-12-02     2.0
6   Cairo 2020-12-03     2.0
7    Giza 2020-12-01     1.0
9    Giza 2020-12-02     2.0
10   Giza 2020-12-03     3.0
Related