You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效计算滚动日期窗口内的事件最大发生次数?

百万级数据下滚动窗口事件数统计的高效实现方案

核心思路

针对百万级数据,要彻底避免逐行遍历或低效的窗口迭代计算,核心是先聚合每日事件数,再用前缀和快速计算滑动窗口和,最后提取最大值。这种方法的时间复杂度为O(n),远优于逐窗口统计的O(n*k)(k为窗口天数),能大幅提升处理效率。

具体步骤

1. 数据预处理

首先将日期列转换为datetime类型,确保时间操作的准确性:

import pandas as pd

# 假设原始数据存储在df中
df['Date of incident'] = pd.to_datetime(df['Date of incident'])

2. 聚合每日事件数

按日期分组统计每日事件发生次数(每条记录计为一次事件),同时补全时间范围内的所有连续日期(无事件的日期计数填充为0):

# 按日期分组,统计每日事件数
daily_counts = df.groupby('Date of incident').size().reset_index(name='count')

# 获取数据集的时间边界
min_date = daily_counts['Date of incident'].min()
max_date = daily_counts['Date of incident'].max()

# 生成连续的日期序列
full_dates = pd.date_range(start=min_date, end=max_date, freq='D')

# 合并连续日期与每日计数,无事件日期补0
daily_counts_full = pd.DataFrame({'Date of incident': full_dates})
daily_counts_full = daily_counts_full.merge(daily_counts, on='Date of incident', how='left').fillna(0)
daily_counts_full['count'] = daily_counts_full['count'].astype(int)

3. 用前缀和计算滑动窗口和

假设窗口大小为window_days(例中为5天),利用前缀和数组快速计算每个窗口的事件总数:

window_days = 5

# 生成前缀和数组
prefix_sum = daily_counts_full['count'].cumsum().values

# 计算每个滚动窗口的事件数
window_sums = []
for i in range(len(prefix_sum)):
    if i < window_days - 1:
        # 处理未填满的初始窗口(从起始日到当前日)
        window_sums.append(prefix_sum[i])
    else:
        # 处理完整窗口:当前日期往前推window_days天的范围
        window_sums.append(prefix_sum[i] - prefix_sum[i - window_days])

# 将窗口结果关联到日期数据
daily_counts_full['window_sum'] = window_sums

4. 提取所有窗口的最大值

直接取窗口和列的最大值即可:

max_incident_count = daily_counts_full['window_sum'].max()
print(f"所有滚动窗口中的最大事件数:{max_incident_count}")

关键优化点

  • 数据压缩:将百万级原始记录聚合为最多几百/几千条日期记录,大幅降低后续计算量。
  • 线性时间计算:前缀和方法是线性时间复杂度,比pandas内置的rolling方法在大样本下更快,尤其是窗口较大时。
  • 内存优化:若数据量极大,可直接用numpy数组替代pandas Series进行前缀和计算,进一步减少内存占用。

扩展:按事件类型分组统计

如果需要按Type分别统计各类型的最大窗口事件数,只需在聚合时增加一层分组:

# 按类型+日期分组统计
daily_counts_by_type = df.groupby(['Type', 'Date of incident']).size().reset_index(name='count')

# 遍历每个类型单独计算
max_counts_by_type = {}
for type_name in daily_counts_by_type['Type'].unique():
    type_data = daily_counts_by_type[daily_counts_by_type['Type'] == type_name]
    # 补全日期、前缀和计算等步骤同前文,此处省略
    # ...
    max_counts_by_type[type_name] = type_window_max

print("各类型最大窗口事件数:", max_counts_by_type)

内容的提问来源于stack exchange,提问作者Ipsider

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 03:27:43