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

如何为DataFrame各ID随机选取指定时长的日期区间数据

问题描述

需要为DataFrame中的每个account_id,在其date字段的最小和最大值范围内,随机选取1周、2周或4周时长的时间区间,并提取该区间内的所有行数据。例如某account_id的日期范围是2022-09-01至2022-09-28,需随机选取如2022-09-06至2022-09-12的7天区间数据。

原思路是随机采样start_date,加上指定时长得到end_date,若end_date超出该ID的最大日期则重新采样,但这种方法会遗漏很多组合,希望找到更优的实现方案。

示例输入数据

import pandas as pd
from pandas import Timestamp

data = [{'account_id': 1, 'date': Timestamp('2022-09-01 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-02 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-03 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-04 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-05 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-06 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-07 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-08 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-09 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-10 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-11 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-12 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-13 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-14 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-15 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-16 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-17 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-18 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-19 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-20 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-21 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-22 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-23 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-24 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-25 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-26 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-27 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-28 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-01 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-02 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-03 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-04 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-05 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-06 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-07 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-08 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-09 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-10 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-11 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-12 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-13 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-14 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-15 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-16 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-17 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-18 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-19 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-20 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-21 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-22 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-23 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-24 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-25 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-26 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-27 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-28 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-29 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-30 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-10-01 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-10-02 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-10-03 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-10-04 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-10-05 00:00:00')}]

df = pd.DataFrame(data)
解决方案

核心思路

直接计算每个account_id下对应所选时长的有效起始日期范围,在该范围内随机选取起始日期,无需重复采样,确保所有可能的有效区间都有被选中的机会:

  • 按account_id分组,获取每组的日期边界
  • 随机选择时长(7/14/28天)
  • 计算该时长下允许的最晚起始日期(最大日期减去时长)
  • 在最小日期到最晚起始日期之间随机选起始日期
  • 筛选起始日期到起始日期+时长范围内的所有行

代码实现

import numpy as np

def random_time_window(group):
    # 获取当前组的最小、最大日期
    min_date = group['date'].min()
    max_date = group['date'].max()
    
    # 可选时长列表(单位:天)
    durations = [7, 14, 28]
    # 随机选一个时长
    duration = np.random.choice(durations)
    
    # 计算允许的最晚起始日期
    latest_start = max_date - pd.Timedelta(days=duration)
    
    # 处理日期范围不足时长的情况(默认取最小日期作为起始)
    if latest_start < min_date:
        start_date = min_date
    else:
        # 生成所有可能的起始日期,随机选一个
        possible_starts = pd.date_range(start=min_date, end=latest_start, freq='D')
        start_date = np.random.choice(possible_starts)
    
    # 计算结束日期
    end_date = start_date + pd.Timedelta(days=duration)
    
    # 筛选区间内的行
    return group[(group['date'] >= start_date) & (group['date'] < end_date)]

# 应用分组处理并重置索引
output = df.groupby('account_id').apply(random_time_window).reset_index(drop=True)

示例输出(随机结果)

output_data = [{'account_id': 1, 'date': Timestamp('2022-09-06 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-07 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-08 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-09 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-10 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-11 00:00:00')},
 {'account_id': 1, 'date': Timestamp('2022-09-12 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-15 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-16 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-17 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-18 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-19 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-20 00:00:00')},
 {'account_id': 2, 'date': Timestamp('2022-09-21 00:00:00')}]

output = pd.DataFrame(output_data)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 01:55:10