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

基于时间索引的NaN前向填充及1小时窗口交易累计统计问询

解决两个Pandas时间序列统计问题

一、基于时间索引实现NaN的前向填充

这个其实很简单,Pandas专门提供了前向填充的方法,直接用ffill()(或者等价的fillna(method='ffill'))就行,前提是你的时间索引已经是Datetime类型的有序索引。

操作步骤:

  1. 先确保时间列是Datetime类型(如果还不是的话):
df['timestamp'] = pd.to_datetime(df['timestamp'])
  1. 设置时间列为索引(如果没设置的话):
df = df.set_index('timestamp')
  1. 执行前向填充:
# 填充整个DataFrame的所有NaN
df_filled = df.ffill()

# 或者只填充特定列,比如某一列叫value
df['value'] = df['value'].ffill()

如果需要限制填充的最大时间间隔(比如只填充1小时内的缺失值),可以结合时间偏移和limit参数,但普通场景用上面的方法就足够了。


二、高效实现按Id分组的过去1小时各交易类型累计统计

你之前用groupby(['Id', 'tradeType'])+rolling('60T')出现NaN,是因为先过滤了特定交易类型,导致其他行没有数据;而遍历行的方法效率低,是因为循环逐行处理完全没用到Pandas矢量化操作的优势。

下面给你一个高效的矢量化方案,数据量越大,对比遍历的效率提升越明显:

核心思路

先把交易类型转成哑变量(0/1),然后按Id分组做1小时滚动求和,直接得到每个时间点过去1小时内各交易类型的累计数量,全程没有NaN,也不需要循环。

完整代码示例

import pandas as pd
from datetime import timedelta

# 1. 预处理:确保时间列是Datetime类型
df['timestamp'] = pd.to_datetime(df['timestamp'])
# 设置时间列为索引(方便后续滚动操作)
df = df.set_index('timestamp')

# 2. 生成交易类型的哑变量:每个类型对应一列,存在该类型则为1,否则为0
dummies = pd.get_dummies(df['tradeType'], prefix='count')  # 列名会变成count_B、count_W等
# 把哑变量和原表的Id列合并
df_with_dummies = pd.concat([df[['Id']], dummies], axis=1)

# 3. 按Id分组,做1小时滚动求和
# rolling('60T')表示窗口为过去60分钟,sum()计算累计数量
rolling_counts = df_with_dummies.groupby('Id').rolling('60T').sum()
# 调整索引:去掉groupby后的Id层级,和原表索引对齐
rolling_counts = rolling_counts.reset_index(level=0, drop=True)

# 4. 合并回原表,得到最终结果
df_final = df.join(rolling_counts)

关键说明

  • 为什么这个方法没有NaN?因为哑变量对不存在的交易类型会填充0,滚动求和时即使过去1小时内没有该类型,结果也是0,完全符合统计需求。
  • 如果需要排除当前行的统计(比如只算当前时间之前1小时的交易,不含当前行),可以给rolling加closed='left'参数:
    rolling_counts = df_with_dummies.groupby('Id').rolling('60T', closed='left').sum()
    
  • 这个方法是纯矢量化操作,效率比遍历行高几个数量级,几万甚至几十万行数据都能秒级处理。

内容的提问来源于stack exchange,提问作者김정민

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 00:12:40