pandas 对于每一天,计算第天和第-1天的唯一用户数,按第三列分组

1sbrub3j  于 2023-01-28  发布在  其他
关注(0)|答案(1)|浏览(123)

我有一个数据集:

      • day**-〉用户执行操作的日期(整数)(例如,day = 1)
      • user_id**-〉标识每个用户的唯一id。(例如user_id ='a'
      • 操作**-〉采取的操作类型(例如,操作= 1)
    • 目标:**
  • 对于天数= n:
  • 对于每个操作:
  • 天数=(n,n-1)(今天和昨天)
  • 计算执行所述操作的唯一用户数。

例如,使用以下数据集:

    • Q**:"第2天有多少用户在第2天和第2 - 1天执行了操作1?"
  • 第2天。
  • 用于操作= 1
  • 天= 2、天= 1-〉a、b、c = 3的唯一用户计数

"我现在的解决方案"
我已经用2个for循环做了一个解决方案,但是我认为有一个更好的解决方案是我缺少的,使用groupby/apply/rolling。但是我无法找到一个更简洁的解决方案。
下面是完整的代码:

import pandas as pd 

df = pd.DataFrame(
    { 
        "day"    :  [ 0,  1,  1,  2,  2,   3 ,  1,   2,   4,   4,   5],
        "user_id":  ['a','a','b','b','c', 'c', 'a', 'b', 'a', 'b', 'c'], 
        "actions" :  [ 1,  1 , 1,  1,  1,   1,   2,   2,   2,   2,   2] 
     
     } 
)

# current soltion with 2 for loops. 
unique_dictionary = {'action': [], 'day': [], 'unique_users_last_n_days': []} # store the results 
n_days = 1 # change the days previous you look at. 

for action in (list(df.actions.unique())):
  for day in (sorted(list(df.day.unique()))):
    mask_last_n_days = (day - df["day"] >=0) & (day - df["day"] <= n_days)  #only look at values that meet condition. 
    mask_action = df['actions'] == action
    unique_users_last_n_days = df[(mask_action) & (mask_last_n_days)]["user_id"].nunique() # get the unique users in the condition 
    # store result in dictionary.  
    unique_dictionary['action'].append(action) 
    unique_dictionary['day'].append(day)
    unique_dictionary['unique_users_last_n_days'].append(unique_users_last_n_days)

df_unique_users_last_n_days = pd.DataFrame(unique_dictionary)

print (df_unique_users_last_n_days)

-OUT
    action  day  unique_users_last_n_days
0        1    0                         1
1        1    1                         2
2        1    2                         3
3        1    3                         2
4        1    4                         1
5        1    5                         0
6        2    0                         0
7        2    1                         1
8        2    2                         2
9        2    3                         1
10       2    4                         2
11       2    5                         3

解决方案应适用于日列中缺失的日期。

mwkjh3gx

mwkjh3gx1#

首先,通过添加n天并在Series.between中过滤,按前几天创建DataFrame列表,按concat添加到原始列表,并按DataFrameGroupBy.nunique获得缺失值数量,最后按Series.reindex添加缺失组合actions, days

n_days = 2 
minday = df['day'].min()
maxday = df['day'].max()

dfs = [(df.assign(day = df['day'].add(day))
         .loc[lambda x: x['day'].between(minday, maxday)]) for day in range(1,n_days+1)]
s = (pd.concat([df, *dfs])
        .groupby(['actions','day'])['user_id']
        .nunique())

mux = pd.MultiIndex.from_product(s.index.levels, names=s.index.names)
df2 = s.reindex(mux, fill_value=0).reset_index()
print (df2)
    actions  day  user_id
0         1    0        1
1         1    1        2
2         1    2        3
3         1    3        3
4         1    4        2
5         1    5        1
6         2    0        0
7         2    1        1
8         2    2        2
9         2    3        2
10        2    4        2
11        2    5        3

相关问题