Pandas 时间序列:查找会话中的间隙,并使用单独的 ID 命名每个会话/间隙
Posted
技术标签:
【中文标题】Pandas 时间序列:查找会话中的间隙,并使用单独的 ID 命名每个会话/间隙【英文标题】:Pandas Time series: find gaps in sessions, and name each session/gap with separate ID 【发布时间】:2021-09-07 16:09:37 【问题描述】:我正在为一个明显简单的任务而苦苦挣扎,希望在这里找到一些帮助!
我有类似以下 DataFrame 的内容。
d = [
['2021-06-01 08:00:00',"A"],
['2021-06-01 09:00:00',"A"],
['2021-06-01 12:00:00',"B"],
['2021-06-01 13:00:00',"B"],
['2021-06-01 18:00:00',"B"],
['2021-06-01 19:00:00',"B"],
['2021-06-01 22:00:00',"C"],
['2021-06-01 23:00:00',"C"]]
df=pd.DataFrame(data=d, columns=("timestamp", "session"))
我想确定一个会话内大于阈值(例如 1 小时)的时间间隔。不应考虑会话之间的时间间隔 为此,我使用了 .diff() 方法来定位间隙。
df["timestamp"]= pd.to_datetime(df["timestamp"])
df["gap"]=df["timestamp"].diff().dt.seconds > 3600
主要任务是在会话中找到一个间隙,并通过重命名部分/会话来将会话分割成片段,例如uuid.uuid4()
.
在示例中,它将导致第 5/6 行中的新会话名称。
我的方法是对独特的会话进行迭代,但是当我在“间隙”列中找到 True 时,我无法重命名这些部分。 我想留在“熊猫世界”,因为这是一项大数据任务。
【问题讨论】:
你能提供一个预期输出的例子吗? 【参考方案1】:你可以这样做:
-
修改您的逻辑以使用
.groupby()
将gap
列设置为session
下的分组
使用GroupBy.cumsum()
获取同一会话中的group
id(新会话名称)(对于每个大于1 小时的时间间隔,单独使用group
id)
使用GroupBy.transform()
为每个组生成 uuid(每个会话的 uuid 不同,同一会话中每个间隙的 uuid 不同)
import uuid
# Keep your existing codes:
df["timestamp"]= pd.to_datetime(df["timestamp"])
# Modify your existing codes:
#df["gap"] = df["timestamp"].diff().dt.seconds > 3600
df["gap"] = df.groupby('session')["timestamp"].diff().dt.seconds > 3600
# New codes:
df['group'] = df.groupby('session')['gap'].cumsum()
df['session_gap_id'] = df.groupby(['session', 'group'], as_index=False)['group'].transform(lambda x: uuid.uuid4())
结果:
这里,每个 session
有不同的会话名称 session_gap_id
,会话中每个不同的组也有单独的 session_gap_id
,包括第 5/6 行(行索引 4/5)
print(df)
timestamp session gap group session_gap_id
0 2021-06-01 08:00:00 A False 0 3cca414b-6bbf-4474-92c4-a0c8273955d8
1 2021-06-01 09:00:00 A False 0 3cca414b-6bbf-4474-92c4-a0c8273955d8
2 2021-06-01 12:00:00 B False 0 9c86305e-fcd6-42c8-b532-39d342a3b35c
3 2021-06-01 13:00:00 B False 0 9c86305e-fcd6-42c8-b532-39d342a3b35c
4 2021-06-01 18:00:00 B True 1 0dbcf66c-ce0d-4b01-93e2-978d77348235
5 2021-06-01 19:00:00 B False 1 0dbcf66c-ce0d-4b01-93e2-978d77348235
6 2021-06-01 22:00:00 C False 0 9b31532c-55c0-4a66-8719-1edbb9047fba
7 2021-06-01 23:00:00 C False 0 9b31532c-55c0-4a66-8719-1edbb9047fba
【讨论】:
【参考方案2】: 您可以使用 groupby / transform 来识别会话中的差距 如果没有预期输出的样本,则不清楚通过创建有间隙的行来实现什么目标d = [
['2021-06-01 08:00:00',"A"],
['2021-06-01 09:00:00',"A"],
['2021-06-01 12:00:00',"B"],
['2021-06-01 13:00:00',"B"],
['2021-06-01 18:00:00',"B"],
['2021-06-01 19:00:00',"B"],
['2021-06-01 22:00:00',"C"],
['2021-06-01 23:00:00',"C"]]
df=pd.DataFrame(data=d, columns=("timestamp", "session"))
df["timestamp"] = pd.to_datetime(df["timestamp"])
df["gap"] = df.groupby("session")["timestamp"].transform(lambda s: s.shift(-1) > s+pd.Timedelta("1h"))
df
timestamp | session | gap |
---|---|---|
2021-06-01 08:00:00 | A | False |
2021-06-01 09:00:00 | A | False |
2021-06-01 12:00:00 | B | False |
2021-06-01 13:00:00 | B | True |
2021-06-01 18:00:00 | B | False |
2021-06-01 19:00:00 | B | False |
2021-06-01 22:00:00 | C | False |
2021-06-01 23:00:00 | C | False |
【讨论】:
以上是关于Pandas 时间序列:查找会话中的间隙,并使用单独的 ID 命名每个会话/间隙的主要内容,如果未能解决你的问题,请参考以下文章
电话间隙 HTML 应用程序可以与 asp.net Mvc Web 服务器建立会话吗