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

分组内每行前后动态天数范围内唯一位置数量统计需求

问题:按分组统计时间窗口内的唯一位置数

给定包含GROUP(分组ID)、DATE(日期)、LOCATION(位置)的数据集,需要针对每个分组中的每一行,统计**过去n1天(含当日)和未来n2天(含当日)**内的唯一位置数量。要求支持动态设置n1和n2,且因数据集规模较大,必须兼顾性能。示例中n1=2、n2=3。

输入数据集

import pandas as pd

data = {
        'GROUP': ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B'],
        'DATE': ['1/01/2023', '1/01/2023', '1/01/2023', '2/01/2023', '2/01/2023', '3/01/2023', '3/01/2023', '3/01/2023', '3/01/2023', '1/06/2023', '2/06/2023', '3/06/2023', '4/06/2023', '5/06/2023', '5/06/2023', '5/06/2023', '6/06/2023'],
        'LOCATION': ['A1', 'A1', 'A2', 'A1', 'A2', 'A2', 'A3', 'A3', 'A4', 'B1', 'B2', 'B2', 'B3', 'B4', 'B2', 'B1', 'B1']
    }
df = pd.DataFrame(data)

期望输出

GROUP       DATE       LOCATION  LOCS_LAST_n1_DAYS  LOCS_NEXT_n2_DAYS
0      A        1/01/2023       A1                 1                 4
1      A        1/01/2023       A1                 1                 4
2      A        1/01/2023       A2                 2                 4
3      A        2/01/2023       A1                 2                 4
4      A        2/01/2023       A2                 2                 3
5      A        3/01/2023       A2                 2                 3
6      A        3/01/2023       A3                 3                 2
7      A        3/01/2023       A3                 3                 2
8      A        3/01/2023       A4                 4                 1
9      B        1/06/2023       B1                 1                 2
10     B        2/06/2023       B2                 2                 2
11     B        3/06/2023       B2                 1                 3
12     B        4/06/2023       B3                 2                 4
13     B        5/06/2023       B4                 2                 3
14     B        5/06/2023       B2                 3                 2
15     B        5/06/2023       B1                 4                 1
16     B        6/06/2023       B1                 3                 1

解决方案

步骤1:标准化日期格式并排序

先将DATE列转为datetime类型,同时按分组和日期排序,确保时间窗口计算的准确性:

df['DATE'] = pd.to_datetime(df['DATE'], format='%d/%m/%Y')
df = df.sort_values(['GROUP', 'DATE']).reset_index(drop=True)

步骤2:按分组聚合日期与位置数据

提前按分组聚合日期列表和对应位置的集合,避免逐行重复计算,提升性能:

grouped = df.groupby('GROUP').agg(
    dates=('DATE', list),
    loc_sets=('LOCATION', lambda x: [set([val]) for val in x])
).reset_index()

步骤3:编写窗口统计函数

定义函数处理单个分组的日期和位置数据,计算每个行对应的过去/未来窗口内的唯一位置数:

def calculate_window_locs(group_dates, group_loc_sets, n1, n2):
    result_last = []
    result_next = []
    date_series = pd.Series(group_dates)
    
    for idx, current_date in enumerate(group_dates):
        # 计算过去n1天的唯一位置数
        mask_last = (date_series >= current_date - pd.Timedelta(days=n1-1)) & (date_series <= current_date)
        locs_last = set().union(*[group_loc_sets[i] for i in mask_last[mask_last].index])
        result_last.append(len(locs_last))
        
        # 计算未来n2天的唯一位置数
        mask_next = (date_series >= current_date) & (date_series <= current_date + pd.Timedelta(days=n2-1))
        locs_next = set().union(*[group_loc_sets[i] for i in mask_next[mask_next].index])
        result_next.append(len(locs_next))
    
    return result_last, result_next

步骤4:应用函数并合并结果

设置n1、n2参数,遍历分组计算后将结果合并回原DataFrame:

n1 = 2
n2 = 3

last_locs = []
next_locs = []

for _, row in grouped.iterrows():
    l, n = calculate_window_locs(row['dates'], row['loc_sets'], n1, n2)
    last_locs.extend(l)
    next_locs.extend(n)

df['LOCS_LAST_n1_DAYS'] = last_locs
df['LOCS_NEXT_n2_DAYS'] = next_locs

# 可选:恢复原日期格式显示
df['DATE'] = df['DATE'].dt.strftime('%d/%m/%Y')
print(df)

性能优化说明

  • 分组聚合预处理:减少全局遍历次数,将计算范围限定在分组内
  • 集合去重合并:利用集合的高效去重特性,替代逐行统计唯一值
  • 向量化日期筛选:使用pandas Series的掩码筛选,比循环判断效率更高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 03:34:56