Pandas时间序列:如何查找会话间隙并为每个会话/间隙命名单独的ID

5
我很困惑一个明显简单的任务,希望在这里寻求帮助!
我有类似下面的 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行出现新的会话名称。

我的方法是对唯一会话进行for循环迭代,但当我在“间隙”列中找到一个True时,无法重命名部分。
我想保持在“pandas世界”中,因为这是一个大数据任务。


1
你能提供一个预期输出的示例吗? - Mateusz Dorobek
2个回答

2
你可以:
  1. 使用.groupby()修改你的逻辑,设置列gap以按session分组。
  2. 使用GroupBy.cumsum()获取同一会话中group id(新会话名称),并为每个大于1小时的时间间隔分别设置group id。
  3. 使用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

0
  • 你可以使用 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

时间戳 会话 间隔
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接