我有一个df,例如下面的示例,我正在寻找标识在给定时间段内发送相同文本的用户,例如该示例的<= 60分钟:
user = [1,2,3,4,5,6]
text = ['hello','hello','whats up','not now','not now','hello']
times = ['2010-09-14 16:51:00','2010-09-14 15:59:00',
'2010-09-14 15:14:00','2010-09-14 14:55:00','2010-09-14 15:47:00','2010-09-14 15:29:00']
df = pd.DataFrame({'userid':user,'message':text,'time':times})
我当前的方法是按向每个文本发送消息的用户列表将文本分组:
group = df.groupby('message')['userid'].apply(list)
然后,我从每个列表中以对值数组的形式返回用户ID的所有可能组合,然后检索每个实例的用户ID文本作为键,以从原始df中检索每个对的每个消息的时间
这种方法有效,但是我一直在尝试寻找更好的方法,根据每个实例之间的时间是否小于指定的时间段(例如本示例为60分钟),有条件地对每个不同文本的用户进行分组来自用户的两条消息之间。因此,用户1和2的“ hello”相距不到60分钟,因此通过条件并将其添加到“ hello”列表中。
因此,该示例的预期输出为:
userid
"hello" [1,2,6]
"not not" [4,5]
我还没有找到任何确切或类似的解决方案,因此非常感谢您的帮助。可能是我解决问题的方法是错误的!
不确定这是最优雅的解决方案-但这是使用group-by
and的解决方案rolling
。这种方法的优点是它可以处理大量数据。它不会创建发送相同消息的所有用户和时间的完整笛卡尔乘积。
res = []
def collect_users(x):
if len(x) > 1:
s = set(x)
if res and res[-1].issubset(s):
res.pop()
res.append(set(x))
return 0
df.groupby("message").rolling("3600s").agg(collect_users)
结果以集合列表的形式出现:
[{1.0, 2.0, 6.0}, {4.0, 5.0}]
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句