高效组合 groupby、last 和 count in pandas
Efficiently combining groupby, last and count in pandas
我想从日志列表中获取特定事件类型在每个时间戳处的活动事件数。
示例日志输入如下所示:
time
id
event
2022-03-01 10:00
1
A
2022-03-01 11:00
2
B
2022-03-01 12:00
3
A
2022-03-01 13:00
1
B
2022-03-01 14:00
4
A
2022-03-01 15:00
2
C
2022-03-01 16:00
1
A
...
...
...
我想要的基本上是在 df 中每次有多少 ids 有活动的事件 A,就像下面的 table。
time
eventA
2022-03-01 10:00
1
2022-03-01 11:00
1
2022-03-01 12:00
2
2022-03-01 13:00
1
2022-03-01 14:00
2
2022-03-01 15:00
2
2022-03-01 16:00
3
...
...
我通过一些基本的 pandas 操作实现了这一点:
df = pd.DataFrame(
{
"time": pd.date_range("2022-03-01 10:00", periods=7, freq="H"),
"id": [1, 2, 3, 1, 4, 2, 1],
"event": ["A", "B", "A", "B", "A", "C", "A"],
}
)
timestamps = df.time
values = []
for timestamp in timestamps:
filtered_df = df.loc[df.time <= timestamp]
eventA = filtered_df.groupby("id").last().groupby("event").count().["time"]["A"]
values.append({"time": timestamp, "eventA": eventA})
df_count = pd.DataFrame(values)
但就我而言,我必须超过 50,000 行,这种基本方法在时间上变得非常低效。
是否有更好的方法来达到预期的效果?我想可能有一些 pandas groupby 聚合方法可以在这里提供帮助,但我发现 none 对我有帮助。
df.set_index(['time', 'id']).unstack().fillna(method='ffill')\
.stack().value_counts(['time', 'event']).unstack().fillna(0)
第一行负责从 id
每个 id
每小时 forward-filling NaN
s
获取最新事件
event
id 1 2 3 4
time
2022-03-01 10:00:00 A NaN NaN NaN
2022-03-01 11:00:00 A B NaN NaN
2022-03-01 12:00:00 A B A NaN
2022-03-01 13:00:00 B B A NaN
2022-03-01 14:00:00 B B A A
2022-03-01 15:00:00 B C A A
2022-03-01 16:00:00 A C A A
第二行进行计数,因此
event A B C
time
2022-03-01 10:00:00 1.0 0.0 0.0
2022-03-01 11:00:00 1.0 1.0 0.0
2022-03-01 12:00:00 2.0 1.0 0.0
2022-03-01 13:00:00 1.0 2.0 0.0
2022-03-01 14:00:00 2.0 2.0 0.0
2022-03-01 15:00:00 2.0 1.0 1.0
2022-03-01 16:00:00 3.0 0.0 1.0
我想从日志列表中获取特定事件类型在每个时间戳处的活动事件数。
示例日志输入如下所示:
time | id | event |
---|---|---|
2022-03-01 10:00 | 1 | A |
2022-03-01 11:00 | 2 | B |
2022-03-01 12:00 | 3 | A |
2022-03-01 13:00 | 1 | B |
2022-03-01 14:00 | 4 | A |
2022-03-01 15:00 | 2 | C |
2022-03-01 16:00 | 1 | A |
... | ... | ... |
我想要的基本上是在 df 中每次有多少 ids 有活动的事件 A,就像下面的 table。
time | eventA |
---|---|
2022-03-01 10:00 | 1 |
2022-03-01 11:00 | 1 |
2022-03-01 12:00 | 2 |
2022-03-01 13:00 | 1 |
2022-03-01 14:00 | 2 |
2022-03-01 15:00 | 2 |
2022-03-01 16:00 | 3 |
... | ... |
我通过一些基本的 pandas 操作实现了这一点:
df = pd.DataFrame(
{
"time": pd.date_range("2022-03-01 10:00", periods=7, freq="H"),
"id": [1, 2, 3, 1, 4, 2, 1],
"event": ["A", "B", "A", "B", "A", "C", "A"],
}
)
timestamps = df.time
values = []
for timestamp in timestamps:
filtered_df = df.loc[df.time <= timestamp]
eventA = filtered_df.groupby("id").last().groupby("event").count().["time"]["A"]
values.append({"time": timestamp, "eventA": eventA})
df_count = pd.DataFrame(values)
但就我而言,我必须超过 50,000 行,这种基本方法在时间上变得非常低效。
是否有更好的方法来达到预期的效果?我想可能有一些 pandas groupby 聚合方法可以在这里提供帮助,但我发现 none 对我有帮助。
df.set_index(['time', 'id']).unstack().fillna(method='ffill')\
.stack().value_counts(['time', 'event']).unstack().fillna(0)
第一行负责从 id
每个 id
每小时 forward-filling NaN
s
event
id 1 2 3 4
time
2022-03-01 10:00:00 A NaN NaN NaN
2022-03-01 11:00:00 A B NaN NaN
2022-03-01 12:00:00 A B A NaN
2022-03-01 13:00:00 B B A NaN
2022-03-01 14:00:00 B B A A
2022-03-01 15:00:00 B C A A
2022-03-01 16:00:00 A C A A
第二行进行计数,因此
event A B C
time
2022-03-01 10:00:00 1.0 0.0 0.0
2022-03-01 11:00:00 1.0 1.0 0.0
2022-03-01 12:00:00 2.0 1.0 0.0
2022-03-01 13:00:00 1.0 2.0 0.0
2022-03-01 14:00:00 2.0 2.0 0.0
2022-03-01 15:00:00 2.0 1.0 1.0
2022-03-01 16:00:00 3.0 0.0 1.0