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

基于Pandas实现多资产半小时时间序列向前填充(ffill)的技术问询

解决方法:生成多资产的半小时时间序列并向前填充

我之前也碰到过一模一样的需求,核心就是先给每个资产生成覆盖起止日期的完整半小时时间轴,再和原始数据合并后按资产分组填充。下面给你一步步拆解实现:

第一步:准备基础环境与参数

首先确保时区统一(你代码里提到了欧洲时区,这里以Europe/London为例),定义好起止日期:

import pandas as pd
from datetime import datetime
import pytz

some_time = datetime(2018,4,2,20,20,42)
tz = pytz.timezone('Europe/London')
# 起始日期设为指定时间的当天0点(带时区)
start_date = datetime(some_time.year, some_time.month, some_time.day, tzinfo=tz)
# 示例结束日期设为起始日次日(你可以根据需求修改)
end_date = start_date + pd.Timedelta(days=1)

第二步:模拟/加载原始数据

假设你的原始数据包含asset_id、timestamp(带时区)和some_property字段,这里先模拟一份测试数据:

raw_data = pd.DataFrame({
    'asset_id': ['A', 'A', 'B', 'B'],
    'timestamp': [
        start_date + pd.Timedelta(hours=1),
        start_date + pd.Timedelta(hours=3),
        start_date + pd.Timedelta(hours=2),
        start_date + pd.Timedelta(hours=4)
    ],
    'some_property': [10, 20, 30, 40]
})

第三步:生成每个资产的完整时间序列

这一步是关键——要确保每个资产都有从start_date到end_date的所有半小时时间点:

# 获取所有唯一的资产ID
unique_assets = raw_data['asset_id'].unique()

# 逐个资产生成完整时间轴
full_time_frames = []
for asset in unique_assets:
    # 创建半小时频率的时间索引(必须和起止日期时区一致)
    time_index = pd.date_range(start=start_date, end=end_date, freq='30min', tz=tz)
    # 组合成该资产的空时间序列DataFrame
    asset_frame = pd.DataFrame({
        'asset_id': [asset] * len(time_index),
        'timestamp': time_index
    })
    full_time_frames.append(asset_frame)

# 合并所有资产的时间序列
full_df = pd.concat(full_time_frames, ignore_index=True)

第四步:合并原始数据并向前填充

把原始数据的some_property值匹配到完整时间轴上,然后按资产分组向前填充缺失值:

# 左连接:保留所有时间点,原始数据存在的点会填充some_property,否则为NaN
merged_df = pd.merge(full_df, raw_data, on=['asset_id', 'timestamp'], how='left')

# 按资产分组,先排序时间再向前填充
final_df = merged_df.groupby('asset_id').apply(
    lambda x: x.sort_values('timestamp').ffill()
).reset_index(drop=True)

备选方法:用groupby + resample(注意坑点)

如果你想用groupby+resample的方式,需要确保原始数据的timestamp是带时区的索引,并且resample时指定时区,否则会出现时区不匹配错误:

# 先把timestamp设为索引
raw_data_indexed = raw_data.set_index('timestamp')
# 分组后按半小时重采样,向前填充
final_df_alt = raw_data_indexed.groupby('asset_id').resample('30min', tz=tz).ffill().reset_index()

⚠️ 注意:这种方法如果原始数据的最早时间晚于start_date,不会生成start_date到原始数据最早时间之间的时间点,所以如果需要完整覆盖起止日期,第一种方法更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:36:29