通过在不与其他值冲突的情况下追加值来生成序列

问题描述

我有如下所示的数据帧

df = pd.DataFrame({'person_id': [101,101,101,101,202,202,202],
                        'login_date':['5/7/2013 09:27:00 AM','09/08/2013 11:21:00 AM','06/06/2014 08:00:00 AM','06/06/2014 05:00:00 AM','12/11/2011 10:00:00 AM','13/10/2012 12:00:00 AM','13/12/2012 11:45:00 AM']})
df.login_date = pd.to_datetime(df.login_date)
df['logout_date'] = df.login_date + pd.Timedelta(days=5)
df['login_id'] = [1,1,1,1,11,11,11]

如果您查看上述数据框中的person_id = 101,他/她在4个不同的时间戳登录和注销,但具有相同的login_id,这是不正确的。

相反,我想为每个唯一的登录会话生成一个新的login_id,其中每个人都会获得一个新的login_id,但在随后的登录中会保留第一个login_id信息。因此,我们可以知道它是一个序列

我尝试了以下方法(基于此post)

cumcount = df.groupby(['person_id','login_id']).login_id.cumcount()
df.login_id = df.login_id.mul(100000).add(cumcount)
虽然对于给定的样例数据集,上面的操作可以很好地工作,但是当存在实际匹配的login_id110000111000021100003时,它可能会失败。因此,如果我将0000100002附加到我login_id = 11,它可能会与原始ID(110000111000021100003)

冲突

我们不必只附加零来表示序列。任何与其他ID不冲突的数字都可以(并且不一定要一个接一个地按顺序排列)。我们只需要获取一些不与其他ID冲突的ID

如何在不与其他用户的其他login_id冲突的情况下,生成一个随机数来指示login_id?我如何决定要追加的数字?

请注意,我想将此应用于大数据,LOGIN_ID可能不仅仅是实际数据中的个位数。例如,第一个LOGIN_ID甚至可以是576869578等类型的随机数。


解决方案

我尝试根据数据帧的长度追加零,以避免与现有ID发生任何冲突。欢迎提出任何改进此解决方案的建议。此操作适用于较小的数据,但不适用于较大的数据帧

cumcount = df.groupby(['person_id','login_id']).login_id.cumcount()
df.login_id = df.groupby(['person_id','login_id']).login_id.transform(lambda x: x.shift().mul(int('1'+'0'*(len(str(len(df)))+1))).fillna(x.min())).add(cumcount)

我认为现在ID不会冲突。有什么建议或建议吗?

输出如下

相关文章