【问题标题】:Longest continuous streaks of multiple users多个用户的最长连续条纹
【发布时间】:2022-01-22 21:25:02
【问题描述】:

我想找到解决办法,

提供了一个表格,其中包含 user_id 和他们访问平台的日期, 找出连续访问时间最长的前100名用户 截至昨天的平台。

我发现这些links 解释了如何为一位用户执行此操作。但是,我不确定如何为多个用户执行此操作。

一个天真的可能是获取所有唯一用户并使用 for 循环和以上答案,获取具有最大连续访问次数的用户。但是,如果可能的话,我对矢量化方式很感兴趣。

如果需要,这些是我使用的代码,

date_series = pd.Series(np.random.randint(0,10, 400), index=pd.to_datetime(np.random.randint(0,20, 400)*1e9*24*3600), name="uid")
df = date_series.reset_index().rename({"index":"date_val"}, axis=1).drop_duplicates().reset_index(drop=True)

对于给定的用户 ID(比如 uid =1),我可以使用以下方法来查找最大连击数,

sub_df = df[df.uid==1].sort_values("date_val")
(sub_df.date_val+pd.Timedelta(days=1) != sub_df.date_val.shift(-1)).cumsum().value_counts().max()

但我不明白如何使用矢量化(不是 for 循环)方法为原始数据帧 (df) 中的所有用户做类似的事情。

【问题讨论】:

  • 您应该提供一个最小的可重现数据集和匹配的预期输出。

标签: python pandas dataframe series


【解决方案1】:

我已经走了很长的路,也许还有更短的路。让我们试试

df=df.sort_values(by=['uid','date_val'])# Sort df


#Check sequence
df=(df.assign(diff=df['date_val'].diff().dt.days,
              diff1=df['date_val'].diff(-1).dt.days))

#create a grouper
s=(((df['diff'].isna())&(df['diff1']==-1))|((df['diff'].gt(1))&(df['diff1']==-1))).cumsum()

#Get streak length
df['streak'] =df.groupby([s,'uid'])['date_val'].transform('count')

#Isolate max streak
new=df[df['streak'] ==df.groupby('uid')['streak'].transform('max')].drop(columns=['diff','diff1']).sort_values(by=['uid','date_val'])

【讨论】:

  • 感谢您的回答,但我认为当下一个用户(比如 uid=2)第一次约会是 uid=1 的最后一天加 1 时,流量会很小。在您的帮助下,我找到了更好的答案,希望可以在下面添加。
  • 去吧,伙计。你比我更了解这个问题。我的尝试是提供帮助。快乐编码:-)
【解决方案2】:

在@wwnde 的回答的帮助下,我找到了以下答案。发布它以防有人发现它有用。

df.sort_values(["uid", "date_val"], inplace=True)  # sort the df

df["diff1"] = df.date_val.diff().dt.days  # new column to store the date diff

df["user_segments"] = ((df.diff1 != 1)|(df.uid != df.uid.shift(-1))).cumsum()  # to create groups of consecutive days

df.groupby(["uid", "user_segments"])["date_val"].count().reset_index()\ # now date_val column have consecutive day counts
.groupby("uid")["date_val"].max()\  # then group by and get the max for each user
.sort_values(ascending=False).iloc[:100]  # finally sort it and get the first 100 users

【讨论】:

    猜你喜欢
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-19
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多