Python 根据另一列中的条件进行分组
我有一个df,如下面的示例,我希望识别在给定时间段内发送相同文本的用户,如一个选项是使用Python 根据另一列中的条件进行分组,python,pandas,numpy,dataframe,pandas-groupby,Python,Pandas,Numpy,Dataframe,Pandas Groupby,我有一个df,如下面的示例,我希望识别在给定时间段内发送相同文本的用户,如一个选项是使用groupby按时间顺序查找下一条匹配的消息,将其合并到原始数据帧,然后过滤到消息间隔
groupby
按时间顺序查找下一条匹配的消息,将其合并到原始数据帧,然后过滤到消息间隔<1小时的地方:
In [402]: df2 = df.merge(df.sort_values("time").groupby("message").shift(), left_index=True, right_index=True, suffixes=["_source", "_target"])
In [403]: df2.loc[df2['time_source'].sub(df2['time_target']).lt("1h"), ["message", "userid_source", "userid_target"]].astype('O')
Out[403]:
message userid_source userid_target
0 hello 1 2
1 hello 2 6
4 not now 5 4
请注意,在您当前的数据中,2和6条消息相隔30分钟,也出现在此处。一个选项是使用groupby
按时间顺序查找下一条匹配消息,将其合并到原始数据框中,然后过滤到消息间隔<1小时的内容:
In [402]: df2 = df.merge(df.sort_values("time").groupby("message").shift(), left_index=True, right_index=True, suffixes=["_source", "_target"])
In [403]: df2.loc[df2['time_source'].sub(df2['time_target']).lt("1h"), ["message", "userid_source", "userid_target"]].astype('O')
Out[403]:
message userid_source userid_target
0 hello 1 2
1 hello 2 6
4 not now 5 4
请注意,在您当前的数据中,2和6条消息相隔30分钟发送给hello
30分钟,也出现在此处。不确定这是最优雅的解决方案-但这里有一个使用分组方式和滚动方式的解决方案。这种方法的优点是,它可以用于大数据集。它不会创建发送相同消息的所有用户和时间的完整笛卡尔积
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}]
不确定它是否是最优雅的解决方案-但这里有一个使用分组方式
和滚动方式
的解决方案。这种方法的优点是,它可以用于大数据集。它不会创建发送相同消息的所有用户和时间的完整笛卡尔积
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}]
您能提供预期的输出吗?另外,当您说“在60分钟内”时,它是否必须在同一小时内(例如12:15和12:45),或者它是否也指12:45和13:15?(少于60分钟,但时间不同)。条件groupby的输出将是每个文本,其中包含在60分钟内发送该文本的用户ID列表。这是两条消息之间的差异,所以跨小时发送是可以的。您能提供预期的输出吗?此外,当您说“在60分钟内”时,它是否必须在同一小时内(例如12:15和12:45),或者它是否也指12:45和13:15?(少于60分钟,但时间不同)。条件groupby的输出将是每个文本,其中包含在60分钟内发送该文本的用户ID列表。这是两条消息之间的区别,所以跨越几个小时就可以了。谢谢你的回复,这看起来很棒,我喜欢这个逻辑。它似乎在我的一部分数据上运行良好,因此我将看到它在整个集合中的运行情况。再次感谢!谢谢你的回复,这看起来很棒,我喜欢这个逻辑。它似乎在我的一部分数据上运行良好,因此我将看到它在整个集合中的运行情况。再次感谢!